Does LINQ to Entities support IEquatable in a 'where' clause predicate?

ぃ、小莉子 提交于 2019-12-07 12:32:19

问题


I have a simple base entity type called EntityBase that implements IEquatable<EntityBase>.

I've used this code outside of LINQ to Entities (with EF 4.1) to filter a list of types derived from EntityBase using a predicate where clause that compares the object instances rather than the ID property they inherit from EntityBase. So basically I want to do this:

UserAccount account = GetMyNewAccount();
Accounts.Where(item => item == account).SingleOrDefault();

rather than this:

UserAccount account = GetMyNewAccount();
Accounts.Where(item => item.Id == account.Id).SingleOrDefault();

Unfortunately, EF 4.1 and specifically LINQ to Entities throws the exception:

Unable to create a constant value of type 'EFTest.UserAccount'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

Does this mean we cannot do a simple object comparison predicate in Entity Framework 4.1 or is my IEquatable implementation wrong in some way?

P.S.: here's the IEquatable code:

public class EntityBase : IEntityBase, IEquatable<EntityBase>
{
    public int Id { get; protected set; }

    #region IEquatable<EntityBase> Members

    public override bool Equals(object obj)
    {
        return Equals(obj as EntityBase);
    }

    public bool Equals(EntityBase other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }

        if (ReferenceEquals(this, other))
        {
            return true;
        }

        if (GetType() != other.GetType())
        {
            return false;
        }

        return Id.Equals(other.Id);
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public static bool operator ==(EntityBase a, EntityBase b)
    {
        if (ReferenceEquals(a, null) && ReferenceEquals(b, null))
        {
            return true;
        }

        if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
        {
            return false;
        }

        return a.Equals(b);
    }

    public static bool operator !=(EntityBase a, EntityBase b)
    {
        return !(a == b);
    }

    #endregion
}

回答1:


It doesn't, no. The C# expressions you pass into Entity Framework linq queries are never executed "as is", but rather the expression tree is evaluated and turned into SQL statements.

Looking at your IEquatable implementation, there's no way it could possibly work - Object.ReferenceEquals() and GetType() cannot be turned into SQL statements..



来源:https://stackoverflow.com/questions/6149018/does-linq-to-entities-support-iequatable-in-a-where-clause-predicate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!