LINQ to Entities是否支持'where'子句谓词中的IEquatable?

时间:2011-05-27 07:14:55

标签: linq-to-entities entity-framework-4.1

我有一个名为EntityBase的简单基本实体类型,它实现了IEquatable< EntityBase>。

我在LINQ to Entities(使用EF 4.1)之外使用了此代码,使用谓词where子句过滤从EntityBase派生的类型列表,该子句比较对象实例而不是它们从中继承的ID属性EntityBase。所以基本上我想这样做:

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

而不是:

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

不幸的是,EF 4.1,特别是LINQ to Entities引发了异常:

  

无法创建“EFTest.UserAccount”类型的常量值。在此上下文中仅支持原始类型(例如Int32,String和Guid')。

这是否意味着我们无法在Entity Framework 4.1中执行简单的对象比较谓词,或者我的IEquatable实现在某种程度上是错误的?

P.S。:这是IEquatable代码:

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 个答案:

答案 0 :(得分:2)

不,不。传递给Entity Framework linq查询的C#表达式永远不会“按原样”执行,而是表达式树被计算并转换为SQL语句。

查看您的IEquatable实现,它无法正常工作 - Object.ReferenceEquals()GetType()无法转换为SQL语句。