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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1001462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:15:37  来源:igfitidea点击:

How do I implement a dynamic 'where' clause in LINQ?

c#linqlinq-to-sql

提问by Waheed

I want to have a dynamic wherecondition.

我想要一个动态where条件。

In the following example:

在以下示例中:

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

Some times I have Titleand sometimes I don't. And also I want to add date in whereclause dynamically.

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

For example, like this SQL:

例如,像这样的 SQL:

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

采纳答案by BFree

You can rewrite it like this:

你可以像这样重写它:

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

EDIT:To answer your question in the comments, yes, you can keep appending to the original Queryable. Remember, this is all lazily executed, so at this point all it's doing it building up the IQueryable so you can keep chaining them together as needed:

编辑:要在评论中回答您的问题,是的,您可以继续附加到原始 Queryable。请记住,这一切都是延迟执行的,因此此时它正在构建 IQueryable,以便您可以根据需要继续将它们链接在一起:

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

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

回答by Joseph

You can dynamically add a where clause to your IQueryable expression like this:

您可以像这样在 IQueryable 表达式中动态添加 where 子句:

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

and for the date similarly.

和日期类似。

However, you will have to wait to create your anonymous type until after you've finished dynamically added your where clauses ifyour anonymous type doesn't contain the fields you want to query for in your where clause.

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

So you might have something that looks like this:

所以你可能有这样的东西:

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

回答by Hugoware

The WHERE clause could be done something like

WHERE 子句可以像

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

Dynamically returning records I don't think is possible in LINQ since it needs to be able to create a consistent AnonymousType (in the background)

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

回答by Daniel Brückner

Because queries are composable, you can just build the query in steps.

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

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

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

回答by Stilgar

If you know in advance all possible where queries like in the SQL example you have given you can write the query like this

如果您事先知道所有可能的查询位置,例如您给出的 SQL 示例,您可以像这样编写查询

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

if you don't know all possible where clauses in advance you can add where dymically for example like this:

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

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

回答by Balaji Birajdar

I was searching for creating a dynamic where clause in LINQ and came across a very beautifull solution on the web which uses ExpressionBuilder in C#.

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

I am posting it here since none of the above solution uses this approach. It helped me. Hope it helps you too http://www.codeproject.com/Tips/582450/Build-Where-Clause-Dynamically-in-Linq

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