Как я реализую динамическое 'где' пункт в LINQ?

Когда я преподавал C ++, нашим стандартным объяснением было то, что они позволяли вам избегать путаницы в солнечный и дождливый день. Другими словами, вы можете написать функцию, как будто все будет работать нормально, и в конце поймать исключение.

Без исключений, вы должны будете получать возвращаемое значение от каждого вызова и гарантировать, что он все еще является законным.

Связанное с этим преимущество, конечно, заключается в том, что вы не «тратите» возвращаемое значение на исключения (и, таким образом, допускаете, чтобы методы, которые должны быть недействительными, считались недействительными), а также можете возвращать ошибки от конструкторов и деструкторов.

12
задан Kev 16 June 2009 в 13:38
поделиться

7 ответов

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

 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(.....);
}
22
ответ дан 2 December 2019 в 04:53
поделиться

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

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

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

-3
ответ дан 26 October 2019 в 06:49
поделиться

Предложение WHERE может быть выполнено примерно как

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

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

1
ответ дан 2 December 2019 в 04:53
поделиться

Вы можете динамически добавить предложение 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
                        };
5
ответ дан 2 December 2019 в 04:53
поделиться

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

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

, если вы не знаете заранее все возможные предложения where, вы можно добавить где динамически, например, вот так:

query = query.Where(item => item.ID != param);
1
ответ дан 2 December 2019 в 04:53
поделиться

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

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

if (someCondition)
{
    query = query.Where(item => anotherCondition(item));
}
1
ответ дан 2 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

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