2012-10-16 51 views
2

我有一个gridview下拉框中的每个标题进行过滤。加载时,每个过滤器都会从其列中加载不同的值。在运行时,我添加“ALL”以允许用户从该字段中选择全部。我试图动态构建linq语句来忽略该字段,如果下拉框设置为“ALL”。这可能吗?我想看看我能否在一个声明中做到这一点。下面的例子只显示了2个下拉框,但我的实际案例已多达5个。Linq动态添加条件的地方

如果我选择使用if语句,我最终得到意大利面代码。

DropDownList drpOwners = this.grdOtherQuotes.HeaderRow.FindControl("drpOwners") as DropDownList;      
DropDownList drpCompanyName = this.grdOtherQuotes.HeaderRow.FindControl("drpCompanyName") as DropDownList; 

var filteredList = (from x in allQuotes 
          where (drpOwners.SelectedValue != ALL) ? x.SalesRepFullName == drpOwners.SelectedValue:true          
           && drpCompanyName.SelectedValue != ALL ? x.CompanyName == drpCompanyName.SelectedValue: true 
          select x); 
+0

你试过linqkit? http://www.albahari.com/nutshell/linqkit.aspx – Parwej

回答

7

个人而言,我觉得有这个破碎更简单:

IEnumerable<Quote> filteredList = allQuotes; 
// If using EF or LINQ to SQL, use: IQueryable<Quote> filteredList = allQuotes; 
if (drpOwners.SelectedValue != ALL) 
    filteredList = filteredList.Where(x => x.SalesRepFullName == drpOwners.SelectedValue); 
if (drpCompanyName.SelectedValue != ALL) 
    filteredList = filteredList.Where(x => x.CompanyName == drpCompanyName.SelectedValue); 
// More conditions as needed 

这真的是没有任何更长,这是更简单跟随。


如果你真的希望能够写本作“一个衬里”,你可以做一个扩展方法来构建查询。例如,如果使用实体框架:

static IQueryable<T> AddCondition(this IQueryable<T> queryable, Func<bool> predicate, Expression<Func<T,bool>> filter) 
{ 
    if (predicate()) 
     return queryable.Where(filter); 
    else 
     return queryable; 
} 

这将然后让你写为:

var filteredList = allQuotes 
        .AddCondition(() => drpOwners.SelectedValue != ALL, x => x.SalesRepFullName == drpOwners.SelectedValue) 
        .AddCondition(() => drpCompanyName.SelectedValue != ALL, x.CompanyName == drpCompanyName.SelectedValue); 

你可以,当然,更进一步借此,使一个版本,硬线谓词检查组合框对“所有”,使谓语更短(只是组合框)。

+0

它基于IQueryable被返回的事实,因此在实际需要数据之前不会执行where子句。 +1 – OmegaMan

+0

@OmegaMan OP不清楚'allQuotes'是'IEnumerable '还是'IQueryable ' - 但是,这实际上与EF一起工作,原来可能不会(我不认为条件运算符在这种情况下,其中“where true”将与EF映射) –

+0

@ReedCopsey - 由于您使用Func ,您的代码将导致查询执行。它应该是表达式> –

1

您可以创建一个处理All逻辑的辅助方法。喜欢的东西:

private bool CompareSelectedValue(string value, string dropDownValue) 
{ 
    if(dropDownValue == "ALL") 
    return true; 
    else 
    return value == dropDownValue; 
} 

然后将查询可能是:

var filteredList = (from x in allQuotes 
          where (CompareSelectedValue(x.SalesRepFullName, drpOwners.SelectedValue)          
           && CompareSelectedValue(x.CompanyName, drpCompanyName.SelectedValue) 
          select x); 
0

创建扩展方法(S),其封装在那里逻辑,所以它看起来更清洁:

var filteredList = allQuotes.WhereDropOwnersAreContained() 
          .WhereCompanyIsContained() 
          ... 
          ;