Поскольку интерфейс IQueryable<out T>
равен ковариант , переданное лямбда-выражение можно использовать напрямую с методом Where
:
var query = queryable.Where(predicate);
Единственная проблема заключается в том, что теперь типрезультат запроса IQueryable<IHasPrice>
.Вы можете вернуть его к IQueryable<Product>
, используя Queryable.Cast
метод:
var query = db.Products.Where(p => p.CustomerId == customerId);
if (predicate != null)
query = query.Where(predicate).Cast<Product>(); // <--
return query.ToList();
Протестировано и работает с последней версией EF Core 2.2 (может не работать в некоторых более ранних версиях).
Альтернативное решение - преобразовать Expression<Func<IHasPrice, bool>>
в ожидаемый Expression<Func<Product, bool>>
, "вызвав" его:
var query = db.Products.Where(p => p.CustomerId == customerId);
if (predicate != null)
{
var parameter = Expression.Parameter(typeof(Product), "p");
var body = Expression.Invoke(predicate, parameter);
var newPredicate = Expression.Lambda<Func<Product, bool>>(body, parameter);
query = query.Where(newPredicate);
}
return query.ToList();