开发者

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

开发者 https://www.devze.com 2023-03-08 22:17 出处:网络
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 derive

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 instanc开发者_开发百科es 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
}


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..

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号