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

时间:2009-06-16 13:23:15

标签: c# linq linq-to-sql

我希望有一个动态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,有时我没有。而且我想动态地在where子句中添加日期。

例如,像这样的SQL:

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

8 个答案:

答案 0 :(得分:22)

您可以这样重写:

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

答案 1 :(得分:5)

您可以动态地将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
                        };

答案 2 :(得分:1)

WHERE子句可以像

那样完成
//...
where string.IsNullOrEmpty(title) ? true : opp.Title.StartsWith(title)
//...

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

答案 3 :(得分:1)

因为查询是可组合的,所以您可以按步骤构建查询。

var query = table.Selec(row => row.Foo);

if (someCondition)
{
    query = query.Where(item => anotherCondition(item));
}

答案 4 :(得分:1)

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

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

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

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

答案 5 :(得分:1)

答案 6 :(得分:0)

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

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

答案 7 :(得分:-3)

使用此:

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。否则,它使用第二个条件,只返回一个子集。

为什么每个人总是让事情变得比他们需要的更复杂?: - )