EF分明(的IEqualityComparer)错误分明、错误、EF、IEqualityComparer

2023-09-02 11:54:12 作者:失色i

早上好!

由于:

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到实体无​​法翻译的Comparer -Exception。 有什么建议?

This will compile, but on runtime I will get an Linq to Entity could not translate Comparer-Exception. Any suggestions?

推荐答案

如果你提供你自己的比较,您将需要执行分明呼叫。 NET code。为了确保这种情况发生,使用 AsEnumerable 打开的IQueryable&LT; T&GT; 的IEnumerable&LT; T&GT ;

If you're providing your own comparisons, you'll need to execute the Distinct call in .NET code. To make sure that happens, use AsEnumerable to turn IQueryable<T> into IEnumerable<T>:

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

当然,在这一点上,你会跨越从数据库中拉更多的数据。另一种方法是对数据进行分组,而不是:

Of course at that point you'll be pulling more data across from the database. An alternative is to group the data instead:

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

这将让你与每个ID所遇到的第一个实体(假设我的查询福不是失败我)。这基本上反正什么不鲜明,但它的所有的数据库。

That will get you the first entity encountered with each ID (assuming my query-fu isn't failing me). That's basically what Distinct does anyway, but it's all at the database.

(请注意,以未来的读者:调用一()更有意义大于 FirstOrDefault(),但显然这不工作。)

(Note to future readers: calling First() makes more sense than FirstOrDefault(), but apparently that doesn't work.)