Когда я преподавал C ++, нашим стандартным объяснением было то, что они позволяли вам избегать путаницы в солнечный и дождливый день. Другими словами, вы можете написать функцию, как будто все будет работать нормально, и в конце поймать исключение.
Без исключений, вы должны будете получать возвращаемое значение от каждого вызова и гарантировать, что он все еще является законным.
Связанное с этим преимущество, конечно, заключается в том, что вы не «тратите» возвращаемое значение на исключения (и, таким образом, допускаете, чтобы методы, которые должны быть недействительными, считались недействительными), а также можете возвращать ошибки от конструкторов и деструкторов.
Вы можете переписать его так:
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(.....);
}
Используйте это:
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. В противном случае он использует второе условие и просто возвращает подмножество.
Почему каждый всегда делает вещи более сложными, чем они должны быть? : -)
Предложение WHERE может быть выполнено примерно как
//...
where string.IsNullOrEmpty(title) ? true : opp.Title.StartsWith(title)
//...
. Я не думаю, что динамический возврат записей возможен в LINQ, поскольку он должен иметь возможность создавать согласованный AnonymousType (в фоновом режиме)
Вы можете динамически добавить предложение 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
};
Следующие вопросы и ответы решают эту проблему достаточно хорошо:
Динамическое предложение where в LINQ - с именами столбцов, доступными во время выполнения
Существует ли шаблон, использующий Linq для динамического создания фильтра?
Если вы заранее знаете все возможные запросы where, подобные приведенному вами примеру SQL, вы можете написать такой запрос
from item in Items
where param == null ? true : ni.Prop == param
select item;
, если вы не знаете заранее все возможные предложения where, вы можно добавить где динамически, например, вот так:
query = query.Where(item => item.ID != param);
Поскольку запросы можно составлять, вы можете просто построить запрос поэтапно.
var query = table.Selec(row => row.Foo);
if (someCondition)
{
query = query.Where(item => anotherCondition(item));
}