【问题标题】:Does LINQ to Entities support IEquatable in a 'where' clause predicate?LINQ to Entities 是否在“where”子句谓词中支持 IEquatable?
【发布时间】:2011-09-03 04:33:20
【问题描述】:

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

我已在 LINQ to Entities 之外使用此代码(使用 EF 4.1)来过滤从 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 尤其是 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
}

【问题讨论】:

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


    【解决方案1】:

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

    查看您的 IEquatable 实现,它不可能工作 - Object.ReferenceEquals()GetType() 不能转换为 SQL 语句..

    【讨论】:

    • 其实这很有意义。现在在我看来,我之前使用的 ORM(Genom-e)(查询工作的地方)实际上并没有使用 IEquatable 方法,而是可能已经将查询表达式转换为键本身的比较 -它知道钥匙,所以完全有可能。
    • 我可以申请其他访问者自己进行 Id 比较的翻译,也可以更改所有谓词。在执行之前修改表达式树应该不会太难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    相关资源
    最近更新 更多