【问题标题】:Build a linq query based on specific criteria c#基于特定条件 c# 构建 linq 查询
【发布时间】:2011-09-29 05:31:35
【问题描述】:

我有一个 List ListPeople“名为 ListPeople 的人员列表”,对象 People 的类是:

class People
{
   public string Name {get;set;}
   public DateTime Dob {get;set;}
   public int Wieght {get;set;}
}

如何使用用户选择的条件执行搜索:类似于:

例如,如果用户会选择以下内容:

然后我会知道如何设置该查询:

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

我是否必须构建 4*4*4(所有可能的组合)数量的查询?

【问题讨论】:

标签: c# linq list search


【解决方案1】:

您不需要提前构建所有可能的组合,您只需要能够继续构建您的查询。初稿:

var myQuery = ListPeople.AsEnumerable();

if (name.Selection == "Is")
    myQuery = myQuery.Where(p => p.Name == nameInput.Text);
else if (name.Selection == /* continues */

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

您可以对 Linq-to-SQL 或 EF 执行相同的操作,您只需使用 AsQueryable() 而不是 AsEnumerable(),这样您就可以在将查询发送到数据库之前完成查询。

var myQuery = context.People.AsQueryable();
// continues

【讨论】:

  • @Tono,我的回答确实有一个错字,请务必检查更新版本。
【解决方案2】:

为了使用 LINQ 执行此操作,您需要提取所有数据,然后编写单独的 where 子句以过滤掉您需要的内容。您可以将所有变量作为字符串传递给函数,以便您可以轻松判断什么是空的。这是您要设置的功能:

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

祝你好运!

编辑: 自从我在这里回答以来,我找到了一种更好的方法来执行这些类型的查询,它将显着提高性能。结帐http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx 此类允许您以字符串格式动态构建 LINQ 查询,然后将其传递给查询。这是我在房地产网站上的房产搜索功能中使用它的一个例子(为了方便而缩小了):

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

祝你好运!

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 2012-12-20
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      相关资源
      最近更新 更多