У нас есть проект, использующий LINQ to SQL, для которого мне нужно переписать пару страниц поиска, чтобы позволить клиенту выбрать, хотят ли они выполнить и или или поиск.
Я думал о повторении запросов LINQ, используя PredicateBuilder , и думаю, что это работает довольно хорошо. У меня фактически есть класс, содержащий мои предикаты, например:
internal static Expression<Func<Job, bool>> Description(string term)
{
return p => p.Description.Contains(term);
}
Чтобы выполнить поиск, я делаю это (некоторый код опущен для краткости):
public Expression<Func<Job, bool>> ToLinqExpression()
{
var predicates = new List<Expression<Func<Job, bool>>>();
// build up predicates here
if (SearchType == SearchType.And)
{
query = PredicateBuilder.True<Job>();
}
else
{
query = PredicateBuilder.False<Job>();
}
foreach (var predicate in predicates)
{
if (SearchType == SearchType.And)
{
query = query.And(predicate);
}
else
{
query = query.Or(predicate);
}
}
return query;
}
Хотя я вполне доволен этим, у меня есть две проблемы:
- Блоки if / else, которые оценивают свойство SearchType, чувствуют, что они могут быть потенциальным запахом кода.
- Клиент теперь настаивает на возможности выполнять поиск, а не «/» или нет.
Что касается пункта 2, я думаю, что я мог бы сделать это, просто переписав мои выражения, например ::
internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
if (invert)
{
return p => !p.Description.Contains(term);
}
else
{
return p => p.Description.Contains(term);
}
}
Однако это похоже на клочок, что обычно означает, что есть лучшее решение. Кто-нибудь может порекомендовать, как это можно улучшить? Мне известно о динамическом LINQ, но я не хочу терять строгую типизацию LINQ.