Linq to entities LINQ to实体是否支持';其中';子句谓词?

Linq to entities LINQ to实体是否支持';其中';子句谓词?,linq-to-entities,entity-framework-4.1,Linq To Entities,Entity Framework 4.1,我有一个简单的基本实体类型EntityBase,它实现了IEquatable 我在LINQtoEntities(4.1版)之外使用了这段代码,使用谓词where子句过滤从EntityBase派生的类型列表,谓词where子句比较对象实例,而不是它们从EntityBase继承的ID属性。所以基本上我想这样做: UserAccount account = GetMyNewAccount(); Accounts.Where(item => item == account).SingleOrDef

我有一个简单的基本实体类型EntityBase,它实现了IEquatable

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

UserAccount account = GetMyNewAccount();
Accounts.Where(item => item == account).SingleOrDefault();
与此相反:

UserAccount account = GetMyNewAccount();
Accounts.Where(item => item.Id == account.Id).SingleOrDefault();
不幸的是,EF 4.1,特别是LINQtoEntities抛出了异常:

无法创建类型为“EFTest.UserAccount”的常量值。在此上下文中仅支持基本类型(“如Int32、String和Guid”)

这是否意味着我们不能在EntityFramework4.1中执行简单的对象比较谓词,或者我的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
}
公共类EntityBase:IEntityBase,IEquatable
{
public int Id{get;protected set;}
#区域可容纳成员
公共覆盖布尔等于(对象对象对象)
{
返回等于(obj作为EntityBase);
}
公共布尔等于(EntityBase其他)
{
if(ReferenceEquals(其他,空))
{
返回false;
}
if(ReferenceEquals(this,other))
{
返回true;
}
如果(GetType()!=other.GetType())
{
返回false;
}
返回Id.Equals(其他Id);
}
公共覆盖int GetHashCode()
{
返回Id.GetHashCode();
}
公共静态布尔运算符==(EntityBase a、EntityBase b)
{
if(ReferenceEquals(a,null)&&ReferenceEquals(b,null))
{
返回true;
}
if(ReferenceEquals(a,null)| | ReferenceEquals(b,null))
{
返回false;
}
返回a等于(b);
}
公共静态布尔运算符!=(EntityBase a、EntityBase b)
{
返回!(a==b);
}
#端区
}
没有。传递到实体框架linq查询中的C#表达式永远不会“按原样”执行,而是对表达式树求值并转换为SQL语句


看看你的
IEquatable
实现,它是不可能工作的-
对象。ReferenceEquals()
GetType()
不能转换成SQL语句。

实际上,这很有意义。在我看来,我以前使用的ORM(Genom-e)(查询工作的地方)实际上根本没有使用IEquatable方法,而是可以将查询表达式转换为键本身的比较-它知道键,所以这是完全可能的。我可以自己应用另一个访问者对Id比较进行转换,或者更改所有谓词。在执行表达式树之前修改它应该不会太难。