GroupBy返回不同的结果

时间:2017-12-22 03:41:10

标签: c# entity-framework linq

IEnumerable<IGrouping<StatusType, Request>> group = requests.GroupBy(r=> r.StatusType );

上述分组功能适用于请求List<Requests>)来自EntityFramework/db的情况。
请求的分配从 db direct 更改为 Web服务时, 分组不按预期工作。

挖掘一下,我发现来自 db StatusType哈希相等是不同的vs web (通过此post找到)。

从帖子的accepted answer开始,我可以通过覆盖来绕过/(解决?)问题。

public class StatusType : IEquatable<int>
{   // omitted other crucial equality comparison components.
    // but for brevity..
    public override int GetHashCode()
    {
        return Id;
    }
}

虽然覆盖StatusType在某种程度上解决了这个问题,但是

我感觉风险很大
  1. 我不是代码库的作者。
  2. StatusType有多个引用增加了潜力 即将发生的失败
  3. 我的问题,

    有没有办法按StatusTypeId分组( int

    requests.groupBy(r=> r.StatusTypeId) // returns IEnumerable<IGrouping<int,Rquest>>
    

    但获得StatusType

    IEnumerable<IGrouping<StatusType,Rquest>>
    

2 个答案:

答案 0 :(得分:5)

定义StatusType的比较器:

public class StatusTypeComparer : IEqualityComparer<StatusType>
{
    public bool Equals(StatusType x, StatusType y)
    {
        return x.Id == y.Id;
    }

    public int GetHashCode(StatusType obj)
    {
        return obj.Id.GetHashCode();
    }
}

将其传递给GroupBy方法:

IEnumerable<IGrouping<StatusType, Request>> group = 
                    requests.GroupBy(r => r.StatusType, 
                                          new StatusTypeComparer());

答案 1 :(得分:0)

免责声明:Backs有一个比我更好的答案,但我认为无论如何我都会为了多样性而发布它。

您可以通过使用多个Linq查询来获得类似于您正在寻找的功能。我不知道我是否可以使用IGrouping的可访问实现,所以我选择了Tuple<StatusType, List<Request>>。它应该有类似的效果。所以,从你原来的查询:

IEnumerable<IGrouping<int, Request>> group = requests.GroupBy(r=> r.StatusTypeId );

您可以添加以下行:

IEnumerable<Tuple<StatusType, List<Request>>> groupByStatusType = 
  group.Select(x => new Tuple<StatusType, List<Request>>(x.First().StatusType, 
                                                         x.ToList()));

或者,您可以在一行中完成所有操作:

IEnumerable<Tuple<StatusType, List<Request>>> group = 
  requests.GroupBy(r => r.StatusTypeId)
          .Select(x => new Tuple<StatusType, List<Request>>(x.First().StatusType, 
                                                            x.ToList()));

您当然可以根据您期望的输出类型来调整查询,但这至少应该让您开始。或者,您可以通过实现迭代所有内容并“手动”创建输出的函数来获得类似的结果。