Build a linq query based on specific criteria c#
I have a List ListPeople "list of people named ListPeople" and the class for an object People is:
class People
{
public string Name {get;set;}
public DateTime Dob {get;set;}
public int Wieght {get;set;}
}
How could I perform a search with criteria chosen by user: Something like:
for example if the user would chose something like:
Then I would know how to set up that query:
var query = (from a in ListPeople
where a.Name == "Tom" &&
a.Weight > 25 &&
a.Dob < "dateTime.Now() - 7 months" // you know what I mean
select a).ToList();
do I have to build 4*4*4 (all posible com开发者_JS百科binations) number of queries?
You do not need to build all possible combinations ahead of time, you just need the ability to keep building upon your query. A rough draft:
var myQuery = ListPeople.AsEnumerable();
if (name.Selection == "Is")
myQuery = myQuery.Where(p => p.Name == nameInput.Text);
else if (name.Selection == /* continues */
You can continue doing this for each of your UI elements to build appropriate predicates for your query and then after you're done, evaluate it as normal.
You can do the same thing for Linq-to-SQL or EF, you just want to use AsQueryable()
instead of AsEnumerable()
so you can finish the query before sending it against the database.
var myQuery = context.People.AsQueryable();
// continues
In order to do this with LINQ, you'd need to pull all the data, then write separate where clauses to filter out what you need. You would pass all variables to the function as a string so that you can easily tell what is empty. This is the function you would setup:
public List<ListPeople> GetPeopleList(string Name, string opName, string Weight, string opWeight, string DOB, string opDOB)
{
var items = from a in ListPeople
select a;
//--- repeat the section below for Weight and DOB
if (!string.IsNullOrEmpty(Name))
{
switch(opName.ToLower())
{
case "contains":
{
items = items.Where(a => SqlMethods.Like(a.Name, "%" + Name + "%"));
break;
}
case "does not contain":
{
items = items.Where(a => !SqlMethods.Like(a.Name, "%" + Name + "%"));
break;
}
case "is":
{
items = items.Where(a => a.Name == Name));
break;
}
case "is not":
{
items = items.Where(a => a.Name != Name));
break;
}
}
}
//--- end repeat
return items.ToList();
}
Good Luck!
EDIT: Since my answer here, I have found a better way to do these types of queries and it will dramatically increase the performance. Checkout http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx This class allows you to build your LINQ query dynamically in a string format and then pass it to the query. Here is an example of how I have used it in a Real Estate website on the property search function (slimmed down for ease):
public IQueryable GetSearchResults(string PriceFrom, string PriceTo, string Beds, string Baths, string SqftFrom, string SqftTo, string YearFrom, string YearTo)
{
DatabaseDataContext db = new DatabaseDataContext();
string WhereClause = string.Empty;
if (!string.IsNullOrEmpty(PriceFrom))
WhereClause = "ListPrice >= " + PriceFrom + " AND ";
if (!string.IsNullOrEmpty(PriceTo))
WhereClause += "ListPrice <= " + PriceTo + " AND ";
if (!string.IsNullOrEmpty(Beds))
WhereClause += "Beds >= " + Beds + " AND ";
if (!string.IsNullOrEmpty(Baths))
WhereClause += "FullBaths >= " + Baths + " AND ";
if (!string.IsNullOrEmpty(SqftFrom))
WhereClause += "SqFtHeated >= " + SqftFrom + " AND ";
if (!string.IsNullOrEmpty(SqftTo))
WhereClause += "SqFtHeated <= " + SqftTo + " AND ";
if (!string.IsNullOrEmpty(YearFrom))
WhereClause += "YearBuilt >= " + YearFrom + " AND ";
if (!string.IsNullOrEmpty(YearTo))
WhereClause += "YearBuilt <= " + YearTo + " AND ";
if (WhereClause.EndsWith(" AND "))
WhereClause = WhereClause.Remove(WhereClause.Length - 5);
IQueryable query = db.Listings
.Where(WhereClause)
.OrderBy("ListPrice descending");
return query;
}
Good Luck!
Have a look at predicate builder.
精彩评论