Использование анонимных типов - как избежать большого количества кода - PullRequest
2 голосов
/ 06 июля 2011

У меня такая ситуация:

if (condition){
   var variable = (from el in ....) //linq to sql query
 }
else{
   var variable = (from el in ....) //linq to sql query
 }

// code where i can`t use the variable

Я хочу избежать копирования кода в обоих условиях.

var getHistoryTips = (from el in objDC.tickets
                      where el.typeOfGame == cANDu[0]
                      && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                      select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault();


var getHistoryTips = (from el in objDC.tickets
                      where el.typeOfGame == cANDu[0]
                      && el.results != null
                      && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                      select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault();

Ответы [ 4 ]

8 голосов
/ 06 июля 2011

Три варианта:

Во-первых, вы можете использовать «пример» - для ввода переменной:

// Same anonymous type properties and types as later:
var variable = Enumerable.Repeat(0, new { ... });

if (condition) {
    variable = ...;
} else {
    variable = ...;
}

В качестве альтернативы вы можете использовать условный оператор:

var variable = condition ? ... first query ...
                         : ... second query ...

В-третьих, вы можете создать запрос, используя вместо этого композицию.Например, если единственным отличием является порядок, вы можете сделать:

var firstPart = ...;

var secondPart = condition ? query.OrderBy(...) : query.OrderByDescending(...);

var query = secondPart.Select(...);

РЕДАКТИРОВАТЬ: Теперь вы привели пример, мы можем сделать этот конкретный:

string username = membership.GetUser(cANDu[1]).ProviderUserKey.ToString();
var query = objDC.tickets
                 .Where(el => el.typeOfGame == cANDu[0] &&
                              el.username == username);

if (condition)
{
    query = query.Where(el => el.results != null);
}

var result = query.Select(el => new { el.AllGamesTickets, el.WGamesTickets})
                  .FirstOrDefault();
2 голосов
/ 06 июля 2011

Вы можете использовать троичный оператор:

var variable = (condition) ? (from el in...) : (from el in...);

Где первый оператор linq-to-sql (перед двоеточием) является истинным регистром, а linq-to-sql после двоеточияэто ложный случай.Таким образом, ваш код может выглядеть так:

var getHistoryTips = (condition) ? (from el in objDC.tickets
                                     where el.typeOfGame == cANDu[0]
                                     && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                                     select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault() : 
                                   (from el in objDC.tickets
                                     where el.typeOfGame == cANDu[0]
                                     && el.results != null
                                     && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                                     select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault();
1 голос
/ 06 июля 2011

Запрошенная вами функциональность может быть реализована с использованием метода расширений вместо синтаксиса LINQ.

Вот пример:

var source = objDC.tickets.Where(el => 
    el.typeOfGame == cANDu[0]
    && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString());

if(condition)
    source = source.Where(el => el.results != null);

var getHistoryTips = source
    .Select(el => new { el.AllGamesTickets, el.WGamesTickets}))
    .FirstOrDefault();

Если запрос усложняется, в качестве опции, селектор может быть реализован с помощью функции Expression.

Expression<Func<ObjDCType, ShallowObjDCType>> selector = 
   (el) => new ShallowObjDC{ el.AllGamesTickets, el.WGamesTickets});

var getHistoryTips = source.Select(selector).FirstOrDefault();

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

Обратите внимание, что вы не можете использовать Func без Expression, поскольку это приведет к тому, что ORM (LINQ / EF) вытянет весь объект из базы данных.

1 голос
/ 06 июля 2011

Используйте ваше условие в самом запросе в предложении where.

Возможно, вам придется написать что-то вроде,

var variable = (from el in .... where (condition && trueBlockCondition) || (!condition && falseBlockCondition) 
...