代码之家  ›  专栏  ›  技术社区  ›  Andreas Niedermair

ef distinct(iequalityComparer)错误

  •  14
  • Andreas Niedermair  · 技术社区  · 16 年前

    早上好!

    鉴于:

    public class FooClass
    {
        public void FooMethod()
        {
            using (var myEntity = new MyEntity)
            {
                var result = myEntity.MyDomainEntity.Where(myDomainEntity => myDomainEntity.MySpecialID > default(int)).Distinct(new FooComparer);
            }
        }
    
    }
    
    public class FooComparer : IEqualityComparer<MyEntity.MyDomainEntity>
    {
        public bool Equals(MyEntity.MyDomainEntity x, MyEntity.MyDomainEntity y)
        {
            return x.MySpecialID == y.MySpecialID;
        }
    
        public int GetHashCode(MyEntity.MyDomainEntity obj)
        {
            return obj.MySpecialID.GetHashCode();
        }
    }
    

    这将编译,但在运行时我将获得 Linq to Entity could not translate Comparer -例外。
    有什么建议吗?

    1 回复  |  直到 16 年前
        1
  •  31
  •   Jon Skeet    16 年前

    如果您提供自己的比较,则需要执行 Distinct 调用.NET代码。要确保发生这种情况,请使用 AsEnumerable 转弯 IQueryable<T> 进入之内 IEnumerable<T> :

    var result = myEntity.MyDomainEntity
            .Where(myDomainEntity => myDomainEntity.MySpecialID > default(int))
            .AsEnumerable()
            .Distinct(new FooComparer());
    

    当然,此时您将从数据库中提取更多的数据。另一种方法是将数据分组:

    var result = from entity in myEntity.MyDomainEntity
                 where entity.MySpecialID > 0
                 group entity by entity.MySpecialID into groups
                 select groups.FirstOrDefault();
    

    这将为您提供每个ID遇到的第一个实体(假设我的查询fu没有失败)。这基本上就是distinct所做的,但都在数据库中。

    (给未来读者的注释:呼叫 First() FirstOrDefault() 但显然不起作用。)