如何使用LINQ获取不同的值?

3

你好,我有一个表格,格式如下=>

    stateID    requestNo    reqStateID       reqStateDate
       1          1             13        03.01.2012 10:57
       2          1              3        03.01.2012 10:58
       3          2              3        03.01.2012 11:14
       4          2              3        03.01.2012 11:15
       5          1              5        03.01.2012 22:28
       6          1              7        05.01.2012 14:54
       7          3              3        05.01.2012 14:55

我需要获取上次添加(reqStateDate)的唯一请求编号(requestNo)。我尝试了类似以下的代码,但并没有成功。

    public List<ReqStates> GetRequests(int reqStateID)
    {
        return  (from rs in db.ReqStates
                          where rs.reqStateID== reqStateID
                          orderby rs.reqStateDate descending
                          select rs).Distinct().ToList();            
    }

如果参数(reqStateID)取3,我必须获取2个请求。requestNo = 2和requestNo = 3。 因为这两个请求的reqstateID都是3,并且它们的添加日期是最新的。 RequestNo = 1 => 最后添加的状态是13。 这就是为什么它(1)不应该出现的原因。
我希望有人能帮助我,并展示一个简单的方法。
3个回答

5

您需要告诉 Distinct 它应该通过什么属性来区分这些值。如果没有指定,将使用默认的相等比较器来区分这些值。

您有两个选项:

  1. 将一个 IEqualityComparer 传递给 distinct。
  2. ReqStates 上实现 IEquatable

示例:

class ReqStatesComparer: IEqualityComparer<ReqStates>
{
  public bool Equals(ReqStates a, ReqStates b)
  {
    return a.requestNo == b.requestNo;
  }

  public int GetHashCode(ReqStates rs)
  {
    return rs.GetHashCode();
  }
}


    public List<ReqStates> GetRequests(int reqStateID)
    {
        return  (from rs in db.ReqStates
                          where rs.reqStateID== reqStateID
                          orderby rs.reqStateDate descending
                          select rs).Distinct(new ReqStatesComparer()).ToList();            
    }

请问您能否给我一个使用IEqualityComparer的示例? - blackraist
非常好的易于理解的例子,我很感激。 - blackraist

3
我不确定您正在寻找什么样的结果,但您正在对整个对象进行去重。因此,对象必须在所有字段上都是唯一的。
请尝试选择一个字段而不是整个对象。然后,修改为仅使用您需要的字段。请尝试以下内容:
return  (from rs in db.ReqStates
                      where rs.reqStateID== reqStateID
                      orderby rs.reqStateDate descending
                      select rs.requestNo).Distinct().ToList();   

我已经尝试过了,但那给了我所有reqStateID等于3的requestNo。第一个条件是request添加日期(reqStateDate)必须是最新的,然后才是reqStateID==3。 - blackraist

2

听起来你想通过ID获取最新的请求,其中包括给定ID的最新reqStateDate。如果是这样,可以执行以下操作:

public List<ReqStates> GetRequests(int reqStateID)
{
    return db.ReqStates.Where(rs => rs.reqStateID == reqStateID)
                       .GroupBy(rs => rs.requestNo)
                       .Select(g => g.OrderByDescending(rs => rs.reqStateDate).First()) 
                       .ToList();            
}

我尝试了这个,但是出现了一个错误:“方法'First'只能用作最终查询操作。在这种情况下,请考虑使用方法'FirstOrDefault'。”我将First()替换为FirstOrDefault(),但是这次出现了“准备命令定义时发生错误。有关详细信息,请参见内部异常。”的错误。 - blackraist
内部异常显示{"指定的方法不受支持。"} - blackraist
@user892945 这是 LINQ to SQL、EF 还是 LINQ to Objects?(以上代码在 LINQ to Objects 中运行正常……) - Reed Copsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接