Как мне реализовать динамическое предложение 'where' в LINQ? - PullRequest
12 голосов
/ 16 июня 2009

Я хочу иметь динамическое условие 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 ]

22 голосов
/ 16 июня 2009

Вы можете переписать это так:

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

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш вопрос в комментариях, да, вы можете продолжать добавлять к исходному Queryable. Помните, что все это выполняется лениво, поэтому на данный момент все, что он делает, создает IQueryable, так что вы можете продолжать связывать их вместе по мере необходимости:

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

if(!String.IsNullOrEmpty(name))
{
   opportunites  = opportunites.Where(.....);
}
5 голосов
/ 16 июня 2009

Вы можете динамически добавить предложение 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
                        };
1 голос
1 голос
/ 16 июня 2009

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

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

если вы заранее не знаете всех возможных положений, где вы можете добавить, где, например, следующим образом:

query = query.Where(item => item.ID != param);
1 голос
/ 16 июня 2009

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

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

if (someCondition)
{
    query = query.Where(item => anotherCondition(item));
}
1 голос
/ 16 июня 2009

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

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

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

0 голосов
/ 20 ноября 2013

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

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

0 голосов
/ 16 июня 2009

Используйте это:

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, он выбирает все, потому что "(DontUseTitles | opp.Title.StartsWith (title))" имеет значение true В противном случае он использует второе условие и просто возвращает подмножество.

Почему все всегда делают вещи более сложными, чем они должны быть? : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...