Как переписать выражения запроса, чтобы заменить перечисления на целые? - PullRequest
17 голосов
/ 19 марта 2011

Вдохновленный желанием использовать перечисления в EF-запросах, я рассматриваю возможность добавления ExpressionVisitor в мои репозитории, который будет принимать входящие критерии / спецификации критериев и переписывать их для использования соответствующего свойства persisted int.

Я последовательно использую следующий шаблон Value-суффикс в моих (сначала кодовых) сущностях:

public class User : IEntity
{
    public long ID { get; set; }

    internal int MemberStatusValue { get; set; }

    public MemberStatus MemberStatus 
    {
        get { return (MemberStatus) MemberStatusValue; }
        set { MemberStatusValue = (int) value; }
    }
}

И сопоставляю это с базой данных, используя следующее:

internal class UserMapping : AbstractMappingProvider<User>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        // adds ToTable and other general mappings
        base.DefineModel( modelBuilder );

        Map.Property( e => e.MemberStatusValue ).HasColumnName( "MemberStatus" );
    }
}

В моих репозиториях у меня есть следующий метод:

public IQueryable<T> Query( Expression<Func<T, bool>> filter, params string[] children )
{
    if( children == null || children.Length == 0 )
    {
        return Objects.Where( filter );
    }
    DbQuery<T> query = children.Aggregate<string, DbQuery<T>>( Objects, ( current, child ) => current.Include( child ) );
    return filter != null ? query.Where( filter ) : query;
}

Я бы хотел добавить вызов метода внутри этого метода, чтобы переписать выражение фильтра, заменив все ссылки на свойство MemberStatus ссылками на MemberStatusValue.

Полагаю, это будет решение, включающее что-то похожее на в этом посте SO , но я точно не знаю, как перейти от идеи к реализации.

Если вы можетедайте какие-либо советы о возможном влиянии на производительность при добавлении этой функции, что также будет оценено.

1 Ответ

1 голос
/ 08 июня 2012

Я не уверен, что это именно то, что вам нужно, но я обнаружил, что проще обрабатывать перечисления похожим, но немного другим способом. Конечно, у меня есть два свойства, как и у вас, но мое свойство int является общедоступным и является тем, что сохраняется в базе данных; Затем у меня есть другое общедоступное свойство «обертки», которое получает / устанавливает значение свойства int посредством приведения типов к / к желаемому перечисляемому типу, который фактически используется остальной частью приложения.

В результате мне не нужно возиться с моделью; EF прекрасно понимает и сохраняет свойство int, а остальная часть приложения получает хорошие взаимодействия с типом enum. Единственное, что мне не нравится в моем подходе, - это то, что я должен написать свои операторы LINQ с кучей приведений к любому значению enum, которое я пытаюсь запросить, чтобы превратить его в int для сопоставления с полем, которое фактически сохраняется. Однако это небольшая цена, и я хотел бы предложить ее вам, поскольку мне кажется, что вы используете строку для генерации запроса, который отказывается от всех типов безопасности, Intellisense и т. Д., Которые предоставляет LINQ.

Наконец, если вы заинтересованы в пошаговом руководстве по использованию новых функций enum в EF 5 (который доступен в бета-версии для загрузки сейчас, если вы хотите попробовать его), проверьте это:

http://msdn.microsoft.com/en-us/hh859576

...