Я сделал себе класс ExpressionBuilder, который помогает мне составлять выражения, которые можно использовать в качестве предиката при выполнении запросов Linq to Sql. Это сработало отлично. Однако я только что обнаружил, что выражения можно использовать только для фильтрации таблиц, а не наборов сущностей? С какой стати это так?
Например, если у меня есть компания и сотрудник с зарплатой. Я мог бы создать эти два выражения:
Expression<Func<Company, bool>> cp = x => x.Name.StartsWith("Micro");
Expression<Func<Employee, bool>> ep = x => x.Name.StartsWith("John");
Затем я ожидаю, что смогу сделать следующее, однако это работает только частично:
var companies = dataContext.Companies
.Where(cp) // Goes fine
.Select(x => new
{
x.Name,
SumOfSalaries = x.Employees
.Where(ep) // Causes compile-time error
.Sum(y => y.Salary),
}
.ToList();
Кроме того, если я делаю ep.Compile()
, он компилируется, но затем я получаю сообщение об ошибке при выполнении запроса.
Почему это так? Я что-то упускаю? Я не нахожу это логичным. Могу ли я это как-то исправить? Или у вас есть хороший обходной путь?
Я знаю, что в этом случае я мог бы просто использовать Where(x => x.Name.StartsWith("John"))
вместо этого, но проблема в том, что выражения, которые мне нужны, не так уж тривиальны. Это более длинные строки из AndAlso
s и OrElse
s.