Linq动态添加条件

时间:2012-10-16 16:42:31

标签: c# linq

我有一个gridview,每个标题中都有下拉框用于过滤。加载时,每个过滤器都会加载其列中的不同值。在运行时,我添加“ALL”以允许用户从该字段中选择所有内容。我正在尝试动态构建linq语句,如果下拉框设置为“ALL”,则忽略该字段。这可能吗?我想看看我是否可以在一个声明中做到这一点。下面的例子只显示了2个下拉框,但实际情况下最多只有5个。

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

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

3 个答案:

答案 0 :(得分: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

这真的不再适用,而且它更容易理解。


如果您真的希望能够将其作为&#34; one-liner&#34;来编写,您可以使用扩展方法来构建查询。例如,如果使用实体框架:

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

当然,您可以更进一步,并制作一个硬连接谓词的版本,以检查组合框对#34; ALL&#34;,使谓词更短(只是组合框)。

答案 1 :(得分: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);

答案 2 :(得分:0)

创建扩展方法,封装where逻辑,使其看起来更干净:

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