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

本文关键字:何避免 代码 类型 | 更新日期: 2023-09-27 18:01:35

我有这样的情况:

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

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

三个选项:

首先,您可以使用"example" -来键入变量:

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

您可以使用三元操作符:

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

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

你可能需要写一些像

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

您所要求的功能可以使用extensions方法来实现,而不是使用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,因为这将导致ORM (LINQ/EF)从数据库中提取所有对象。