Подтвердить что ты не робот

Как переписать выражения запросов для замены перечислений с помощью ints?

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

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

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, но я точно не знаю, как перейти от идеи к реализации.

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

4b9b3361

Ответ 1

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

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

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

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