我正在创建一个IQueryable,用于传递到实体框架的查询。我的存储库不公开可查询的。
var query = new List<Entity>().AsQueryable().Where(x => x.Property == "argument");
我在我的存储库中有一个方法,它将接受IQueryable。
如何使用相同的queryable查询我的DbSet?我正试图从queryable中提取表达式,以便为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;
}
当我尝试创建lambda时,代码失败,并出现以下错误:类型为"System.Linq.IQueryable `1[MyTEntity]"的表达式不能用于返回类型"System.Boolean"
我显然没有正确地构建表达式,我缺少什么?有没有一种更简单的方法来完成我想要完成的事情?
此外,我还看到了一些示例,显示表达式应该具有parameters属性。但是,无论我转换为哪种类型的表达式类型,这是ConstantExpression,我都看不到IQueryable.expression.
在您的例子中,queryable.Expression
表示整个表达式Queryable.Where(constantList, x => x.Property == "argument")
。如果你只想要Where()
lambda,你需要提取它
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;
}