Поддерживает ли LINQ to Entities IEquatable в предикате предложения where? - PullRequest
3 голосов
/ 27 мая 2011

У меня есть простой базовый тип сущности, называемый EntityBase, который реализует IEquatable .

Я использовал этот код вне LINQ to Entities (с EF 4.1) для фильтрациисписок типов, полученных из EntityBase с использованием предиката where, который сравнивает экземпляры объекта, а не свойства 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что-то не так?

PS: вот код 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 Ответ

2 голосов
/ 27 мая 2011

Нет, нет.Выражения C #, которые вы передаете в запросы Entity Framework linq, никогда не выполняются «как есть», а вместо этого дерево выражений оценивается и превращается в операторы SQL.возможно работает - Object.ReferenceEquals() и GetType() нельзя превратить в операторы SQL ..

...