简体   繁体   English

基于特定条件 c# 构建 linq 查询

[英]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:我有一个列表 ListPeople“名为 ListPeople 的人员列表”和 object People 的 class 是:

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 combinations) number of queries?我是否必须构建 4*4*4(所有可能的组合)数量的查询?

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.您可以继续为每个 UI 元素执行此操作,以便为您的查询构建适当的谓词,然后在完成后正常评估它。

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.您可以对 Linq-to-SQL 或 EF 执行相同的操作,您只想使用AsQueryable()而不是AsEnumerable() ,以便在将查询发送到数据库之前完成查询。

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.为了使用 LINQ 执行此操作,您需要提取所有数据,然后编写单独的 where 子句以过滤掉您需要的内容。 You would pass all variables to the function as a string so that you can easily tell what is empty.您可以将所有变量作为字符串传递给 function,以便您可以轻松判断什么是空的。 This is the function you would setup:这是您要设置的 function:

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. 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以字符串格式动态查询,然后将其传递给查询。 Here is an example of how I have used it in a Real Estate website on the property search function (slimmed down for ease):以下是我如何在房地产网站上的房地产搜索 function 中使用它的示例(为方便起见,已精简):

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 .看看谓词生成器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM