Перевод выражений IQueryable

Я создаю IQueryable, который я хочу использовать для запроса, переданного в платформу сущностей. Мой репозиторий не предоставляет возможность запроса.

 var query = new List<Entity>().AsQueryable().Where(x => x.Property == "argument");

У меня есть метод в моем хранилище, который принимает IQueryable.

Как я могу запросить мой DbSet с тем же запросом? Я пытаюсь извлечь выражение из запрашиваемого для создания нового выражения для базы данных. Вот то, что у меня есть, но оно не работает:

public IDbSet<TEntity> DbSet { get; set; }

public IEnumerable<TEntity> Find(IQueryable<TEntity> queryable)
{
      var parameter = Expression.Parameter(typeof (TEntity));
      var body = queryable.Expression;

      var lambda = Expression.Lambda<Func<TEntity, bool>>(body, parameter);
      var result =  DbSet.Where(lambda);
      return null;
}

Код не выполняется, когда я пытаюсь создать лямбду со следующей ошибкой: Выражение типа 'System.Linq.IQueryable`1[MyTEntity]' нельзя использовать для типа возвращаемого значения 'System.Boolean'

Я явно не правильно строю выражение, что мне не хватает? Есть ли более простой способ сделать то, что я пытаюсь сделать?

Также я видел несколько примеров, которые показывают, что выражение должно иметь свойство параметров. Но независимо от того, к какому типу выражения я приведу тип, а это ConstantExpression, я не вижу свойства параметров из IQueryable.Expression.

1 ответ

В твоем случае, queryable.Expression представляет собой целое выражение Queryable.Where(constantList, x => x.Property == "argument"), Если вы хотите только Where() лямбда, тебе нужно извлечь его. Чтобы сделать это, вы можете использовать такой код:

public IEnumerable<TEntity> Find<TEntity>(IQueryable<TEntity> queryable)
{
    var methodCall = queryable.Expression as MethodCallExpression;
    Func<IQueryable<TEntity>, Expression<Func<TEntity,Boolean>>, IQueryable<TEntity>> whereDelegate = Queryable.Where;

    if (methodCall.Method == whereDelegate.Method
        && methodCall.Arguments[0] is ConstantExpression)
    {
        var whereLambdaQuote = (UnaryExpression)methodCall.Arguments[1];
        var whereLambda = (Expression<Func<TEntity, bool>>)whereLambdaQuote.Operand;

        var result = DbSet.Where(whereLambda);
    }

    return null;
}
Другие вопросы по тегам