Проблема, похоже, заключается в использовании константного выражения анонимного типа, которое в настоящее время вызывает оценку клиента , а оператор C # ==
сравнивает анонимные типы по ссылке, поэтому всегда возвращает false
.
Хитрость для получения желаемого перевода сервера состоит в том, чтобы "вызвать" выражение key
с entity
, заменив параметр на Expression.Constant(entity)
(Expression.Invoke
в этом случае не работает)
Удалите строку var getKeyFunction = key.Compile();
, если она больше не нужна, и используйте следующее:
foreach (var entity in entities)
{
var parameter = key.Parameters[0];
var body = Expression.Equal(
key.Body,
key.Body.ReplaceParameter(parameter, Expression.Constant(entity))
);
var query = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
var exist = await table.AnyAsync(query);
// ...
}
, где ReplaceParameter
- это обычный вспомогательный метод выражения:
public static partial class ExpressionUtils
{
public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
=> new ParameterReplacer { Source = source, Target = target }.Visit(expression);
class ParameterReplacer : ExpressionVisitor
{
public ParameterExpression Source;
public Expression Target;
protected override Expression VisitParameter(ParameterExpression node)
=> node == Source ? Target : node;
}
}