LINQ中的动态WHERE子句

Kei*_*ows 54 c# linq dynamic where-clause

将动态WHERE子句组装到LINQ语句的最佳方法是什么?

我在表单上有几十个复选框,并将它们传递回:Dictionary <string,List <string >>(Dictionary <fieldName,List <values >>)到我的LINQ查询.

public IOrderedQueryable<ProductDetail> GetProductList(string productGroupName, string productTypeName, Dictionary<string,List<string>> filterDictionary)
{
    var q = from c in db.ProductDetail
            where c.ProductGroupName == productGroupName && c.ProductTypeName == productTypeName
            // insert dynamic filter here
            orderby c.ProductTypeName
            select c;
    return q;
}
Run Code Online (Sandbox Code Playgroud)

Tho*_*ock 53

alt text http://www.scottgu.com/blogposts/dynquery/step2.png

你需要这样的东西吗?使用Linq动态查询库(下载包含示例).

查看ScottGu的博客了解更多示例.


Xav*_*ohn 14

我有类似的场景,我需要根据用户输入添加过滤器,并链接where子句.

这是示例代码.

var votes = db.Votes.Where(r => r.SurveyID == surveyId);
if (fromDate != null)
{
    votes = votes.Where(r => r.VoteDate.Value >= fromDate);
}
if (toDate != null)
{
    votes = votes.Where(r => r.VoteDate.Value <= toDate);
}
votes = votes.Take(LimitRows).OrderByDescending(r => r.VoteDate);
Run Code Online (Sandbox Code Playgroud)

  • 精彩的答案! (2认同)

Lin*_*nus 13

您还可以使用LinqKit中的PredicateBuilder使用Or或And链接多个类型安全的lambda表达式.

http://www.albahari.com/nutshell/predicatebuilder.aspx


Nit*_*rai 8

如果您的列是像String这样的简单类型,则可以使用简单的方法

public static IEnumerable<MyObject> WhereQuery(IEnumerable<MyObject> source, string columnName, string propertyValue)
{
   return source.Where(m => { return m.GetType().GetProperty(columnName).GetValue(m, null).ToString().StartsWith(propertyValue); });
}
Run Code Online (Sandbox Code Playgroud)

  • 我的应用程序抱怨这无法转换为 SQL(我正在使用 Postgres 提供程序)。也许您的代码在内存中而不是数据库上运行?这会导致大型数据集上的性能不佳。 (2认同)

小智 8

使用三元运算符动态决定是否包含条件似乎越来越简单

List productList = new List();

        productList =
                db.ProductDetail.Where(p => p.ProductDetailID > 0 //Example prop
                && (String.IsNullOrEmpty(iproductGroupName) ? (true):(p.iproductGroupName.Equals(iproductGroupName)) ) //use ternary operator to make the condition dynamic
                && (ID == 0 ? (true) : (p.ID == IDParam))
                ).ToList();
Run Code Online (Sandbox Code Playgroud)


mik*_*ike 5

我提出了一个解决方案,即使我能理解......通过使用'Contains'方法,您可以根据需要链接尽可能多的WHERE.如果WHERE是一个空字符串,则忽略它(或者将其评估为全选).这是我在LINQ中连接2个表的示例,应用多个where子句并填充要返回到视图的模型类.(这是一个全选).

public ActionResult Index()
    {
        string AssetGroupCode = "";
        string StatusCode = "";
        string SearchString = "";

        var mdl = from a in _db.Assets
                  join t in _db.Tags on a.ASSETID equals t.ASSETID
                  where a.ASSETGROUPCODE.Contains(AssetGroupCode)
                  && a.STATUSCODE.Contains(StatusCode)
                  && (
                  a.PO.Contains(SearchString)
                  || a.MODEL.Contains(SearchString)
                  || a.USERNAME.Contains(SearchString)
                  || a.LOCATION.Contains(SearchString)
                  || t.TAGNUMBER.Contains(SearchString)
                  || t.SERIALNUMBER.Contains(SearchString)
                  )
                  select new AssetListView
                  {
                      AssetId = a.ASSETID,
                      TagId = t.TAGID,
                      PO = a.PO,
                      Model = a.MODEL,
                      UserName = a.USERNAME,
                      Location = a.LOCATION,
                      Tag = t.TAGNUMBER,
                      SerialNum = t.SERIALNUMBER
                  };


        return View(mdl);
    }
Run Code Online (Sandbox Code Playgroud)