使用匿名类型 - 如何避免大量代码

时间:2011-07-06 18:14:57

标签: c# asp.net linq-to-sql

我遇到这种情况:

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 个答案:

答案 0 :(得分:8)

三个选项:

首先,您可以使用“示例” - 键入变量:

// 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();

答案 1 :(得分:2)

您可以使用三元运算符:

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();

答案 2 :(得分:1)

在where子句中使用查询本身的条件。

您可能需要写一些类似的内容,

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

答案 3 :(得分:1)

您要求的功能可以使用扩展方法实现,而不是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<Func<ObjDCType, ShallowObjDCType>> selector = 
   (el) => new ShallowObjDC{ el.AllGamesTickets, el.WGamesTickets});

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

这项技术将允许你在其他函数中传递选择器,以防事情变得越来越复杂,但它需要你定义其他类或使用动态而不是匿名类。

请注意,您不能在没有Expression的情况下使用Func,因为这会导致ORM(LINQ / EF)从数据库中提取所有对象。