12

Вопрос по linq-to-sql, c#, linq – Как мне реализовать динамическое предложение 'where' в 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 { ...

Имейте в виду, что вы на самом деле не<i>writing</i> [T] SQL здесь ... вы пишете C #

от Marc Gravell♦

8 ответов

1

Следующие вопросы и ответы решают это довольно хорошо:

Dynamic where clause in LINQ - with column names available at runtime
Is there a pattern using Linq to dynamically create a filter?

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

EDIT: Чтобы ответить на ваш вопрос в комментариях, да, вы можете продолжать добавлять к исходному Queryable. Помните, что все это выполняется лениво, поэтому на данный момент все это делает это, создавая IQueryable, чтобы вы могли продолжать объединять их в цепочки по мере необходимости:

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

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

Поскольку запросы являются составными, вы можете просто создать запрос в пошаговом режиме.

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

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

Если вы заранее знаете все возможные варианты запросов, как в приведенном вами примере SQL, вы можете написать запрос следующим образом.

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

если вы заранее не знаете всех возможных положений «где», вы можете добавить «где двойным образом», например, вот так:

query = query.Where(item => item.ID != param);
-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, он выбирает все, потому что & quot; (DontUseTitles | opp.Title.StartsWith (title)) & quot; оценивает как истинное. В противном случае он использует второе условие и просто возвращает подмножество.

Why does everyone always make things more complex than they need to be? :-)

0

Я искал создание динамического предложения where в LINQ и наткнулся на очень красивое решение в сети, которое использует ExpressionBuilder в C #.

Я размещаю это здесь, так как ни одно из вышеупомянутого решения не использует этот подход. Это помогло мне. Надеюсь, это вам тоже поможет http://www.codeproject.com/Tips/582450/Build-Where-Clause-Dynamically-in-Linq

5

Вы можете динамически добавить предложение where к своему выражению IQueryable следующим образом:

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

и на дату аналогично.

Однако вам придется подождать, пока вы создадите свой анонимный тип, до тех пор, пока вы не закончите динамически добавлять предложения where.if Ваш анонимный тип не содержит полей, которые вы хотите запросить в предложении 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
                        };
1

Предложение WHERE может быть сделано что-то вроде

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

Динамическое возвращение записей, я не думаю, что это возможно в LINQ, поскольку он должен иметь возможность создавать согласованный тип AnonymousType (в фоновом режиме)

Похожие вопросы