Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
320 views
in Technique[技术] by (71.8m points)

c# - Linq dynamically adding where conditions

I have a gridview which has drop down boxes in each header for filtering. Each filter is loaded with the distinct values from its column when loaded. At run time, I add "ALL" to allow the user to select all from that field. I am trying to build the linq statement dynamically to ignore the field if the drop down box is set to "ALL". Is this possible? I want to see if I can do this in one single statement. The example below only shows 2 dropdown boxes, but my actually case has up to 5.

If I choose to use if then statements, I end up with spaghetti code.

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);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Personally, I'd find having this broken up to be simpler:

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

This really isn't any longer, and it's far simpler to follow.


If you really wanted to be able to write this as a "one-liner", you could make an extension method to build the query. For example, if using Entity Framework:

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

This would then let you write this as:

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

You could, of course, take this even further, and make a version that hard-wires the predicate to check a combo box against "ALL", making the predicate shorter (just the combo box).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...