Выражение такое: x => x.UserRoles.Any(y => y.RoleNo == 100101) где x имеет тип UserEntity, y имеет тип UserRoleEntity, а 100101 может быть любым целочисленным идентификатором роли.
При этом возникает следующее исключение: «System.InvalidOperationException: 'Выражение LINQ 'y' не может быть переведено. Либо перепишите запрос в форме, которую можно перевести, либо явно переключитесь на оценку клиента, вставив вызов в «AsEnumerable», «AsAsyncEnumerable», «ToList» или «ToListAsync».
Я также нахожу это исключение неясным, поскольку оно жалуется на «y», который является параметром для вложенная лямбда. Не могу себе представить, что может быть не так в этой части выражения.
Код: Выделить всё
public async Task GetByCriteria(ICriteria criteria)
{
// Using an expression in code
var test = _dbContext.Set()
.Where(x => x.UserRoles.Any(y => y.RoleNo == 100101)).AsNoTracking();
List codeEntities = await test.ToListAsync();
Код: Выделить всё
public async Task GetByCriteria(ICriteria criteria)
{
Expression expression = criteria.AsExpression();
// Using a generated expression
var queryable = _dbContext.Set()
.Where(expression).AsNoTracking();
List exprEntities = await queryable.ToListAsync();
Я попробовал запустить закодированное выражение вместо сгенерированного объекта Expression, который показывает, что Я использую правильную лямбду.
Я также пробовал работать с вызовом AsNoTracking() и без него. Это не имеет значения.
Я сравнил объекты Queryable из двух примеров в отладчике и не обнаружил различий между ними.
Я пробовал работает вне отладчика и по-прежнему получает исключение.
Если я помещу оба набора примеров кода вместе, чтобы сначала запускалась закодированная лямбда-выражение, а затем запускалось сгенерированное выражение, исключение < strong>не бывает. Я предполагаю, что это связано с тем, что EF кэшировал первый (успешный) запрос и не пытается снова запросить второй.
ОБНОВЛЕНИЕ:Я рассмотрел PredicateBuilder от LinqKit как возможный способ упростить свой код и облегчить поиск ошибок. К сожалению, он не может сделать то, на что я надеялся. Это упрощает построение выражения верхнего уровня, которое представляет собой серию логических операторов И, но ничего не дает для построения реальных условных выражений, что здесь является самой сложной частью. Мне нужно иметь возможность брать динамические имена свойств, значения и операторы и компоновать их вместе, поэтому, похоже, Expression API по-прежнему остается единственным выходом.
Я продолжу анализировать свои код, чтобы найти разницу между закодированными и сгенерированными выражениями.
ОБНОВЛЕНИЕ:
Я обнаружил проблему и опубликовал подробности ниже в новом ответ. Спасибо всем, кто подал мне идеи.
Подробнее здесь: https://stackoverflow.com/questions/784 ... erated-exp