如何在LINQ中实现动态“where”子句?

我希望有一个动态的条件。

在以下示例中:

 var opportunites = from opp in oppDC.Opportunities join org in oppDC.Organizations on opp.OrganizationID equals org.OrgnizationID where opp.Title.StartsWith(title) select new { opp.OpportunityID, opp.Title, opp.PostedBy, opp.Address1, opp.CreatedDate, org.OrganizationName }; 

有时我有Title ,有时候我没有Title 。 而且我想动态地在where子句中添加日期。

例如,像这样的SQL:

 string whereClause; string SQL = whereClause == string.Empty ? "Select * from someTable" : "Select * from someTable" + whereclause 

你可以像这样重写它:

  var opportunites = from opp in oppDC.Opportunities join org in oppDC.Organizations on opp.OrganizationID equals org.OrgnizationID select new { opp.OpportunityID, opp.Title, opp.PostedBy, opp.Address1, opp.CreatedDate, org.OrganizationName }; if(condition) { opportunites = opportunites.Where(opp => opp.Title.StartsWith(title)); } 

编辑:要在评论中回答您的问题,是的,您可以继续附加到原始的可查询。 记住,这都是懒惰的执行,所以在这一点上,所有它都在构建IQueryable,这样你就可以根据需要将它们链接在一起:

 if(!String.IsNullOrEmpty(title)) { opportunites = opportunites.Where(.....); } if(!String.IsNullOrEmpty(name)) { opportunites = opportunites.Where(.....); } 

您可以动态地将where子句添加到IQueryable表达式,如下所示:

 var finalQuery = opportunities.Where( x => x.Title == title ); 

和类似的日期。

但是, 如果匿名类型不包含要在where子句中查询的字段,则必须等到创建匿名类型,直到完成动态添加where子句为止。

所以你可能会看到这样的东西:

 var opportunities = from opp in oppDC.Opportunities join org in oppDC.Organizations on opp.OrganizationID equals org.OrgnizationID select opp if(!String.IsNullOrEmpty(title)) { opportunities = opportunities.Where(opp => opp.Title == title); } //do the same thing for the date opportunities = from opp in opportunities select new { opp.OpportunityID, opp.Title, opp.PostedBy, opp.Address1, opp.CreatedDate, org.OrganizationName }; 

WHERE子句可以像这样完成

 //... where string.IsNullOrEmpty(title) ? true : opp.Title.StartsWith(title) //... 

动态返回记录我认为在LINQ中是不可能的,因为它需要能够创建一致的AnonymousType(在后台)

由于查询是可组合的,因此您可以按步骤构建查询。

 var query = table.Selec(row => row.Foo); if (someCondition) { query = query.Where(item => anotherCondition(item)); } 

以下问题和答案很好地解决了这个问题:

LINQ中的动态where子句 – 在运行时可用列名
是否有使用Linq动态创建filter的模式?

如果您事先知道所有可能的情况,那么您给出的SQL示例中的查询可以像这样编写查询

 from item in Items where param == null ? true : ni.Prop == param select item; 

如果你事先不知道所有可能的where子句,你可以添加dymically例如:

 query = query.Where(item => item.ID != param); 

我正在寻找在LINQ中创建一个动态的where子句,并在Web上遇到了一个非常漂亮的解决方案,该解决方案在C#中使用ExpressionBuilder。

我在这里发布它,因为上述解决方案都没有使用这种方法。 它帮助了我。 希望它也能帮助你http://www.codeproject.com/Tips/582450/Build-Where-Clause-Dynamically-in-Linq

用这个:

 bool DontUseTitles = true; // (Or set to false... var opportunites = from opp in oppDC.Opportunities join org in oppDC.Organizations on opp.OrganizationID equals org.OrgnizationID where (DontUseTitles | opp.Title.StartsWith(title)) select new { opp.OpportunityID, opp.Title, opp.PostedBy, opp.Address1, opp.CreatedDate, org.OrganizationName }; 

它为什么有效? 如果DontUseTitles为true,则选择all,因为“(DontUseTitles | opp.Title.StartsWith(title))”的计算结果为true。 否则,它使用第二个条件并返回一个子集。

为什么每个人总是把事情变得比他们需要的更复杂? 🙂