dynamicLINQ中的WHERE子句

什么是最好的方式来组装dynamic的WHERE子句的LINQ语句?

我有一个窗体上的几十个checkbox,并将它们传回给我的LINQ查询:Dictionary <string,List <string >>(Dictionary <fieldName,List <values >>)。

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

替代文字blogposts/dynquery/step2.png

你需要这样的东西? 使用Linqdynamic查询库 (下载包含示例)。

看看ScottGu的博客更多的例子。

您也可以使用LinqKit中的PredicateBuilder使用Or或And来链接多个types安全的lambdaexpression式。

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

一个简单的方法可以是,如果你的列是简单的types像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); }); } 

我想出了一个解决scheme,即使我可以理解…通过使用“包含”方法,您可以链接尽可能多的地方,只要你喜欢。 如果WHERE是一个空string,它将被忽略(或被评估为全选)。 这里是我在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); } 

我有类似的情况下,我需要添加基于用户inputfilter,我链条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); 

我有同样的问题( 用户定义filter的linq ),和@ tvanfosson告诉我有关dynamicLinq( http://code.msdn.microsoft.com/csharpsamples )。

你可以使用Any()扩展方法。 以下似乎为我工作。

 XStreamingElement root = new XStreamingElement("Results", from el in StreamProductItem(file) where fieldsToSearch.Any(s => el.Element(s) != null && el.Element(s).Value.Contains(searchTerm)) select fieldsToReturn.Select(r => (r == "product") ? el : el.Element(r)) ); Console.WriteLine(root.ToString()); 

where'fieldsToSearch'和'fieldsToReturn'都是List对象。

CodePlex上的这个项目有你想要的。

System.Linq.Dynamichttp://dynamiclinq.codeplex.com/

项目介绍

扩展System.Linq.Dynamic,以支持对entity framework或任何支持IQueryable的提供者执行的string中定义的Lambdaexpression式。

因为它是源代码的扩展,你可以在Scott Guthrie的博客上find它,它可以让你做这样的事情:

在这里输入图像说明

而这样的事情:

在这里输入图像说明