【发布时间】:2023-04-02 14:15:01
【问题描述】:
我写了一些谓词,希望它们构造一个实体查询。
通常如果我有一个EntityA 类型的实体,我会写这种表达式Expression<Func<EntityA, bool>>。
我想要完成的是在 EntityA 类型的查询中使用 Expression<Func<EntityB, bool>>。
假设EntityA 有一个EntityB 的集合。我对EntityA 有一个谓词,例如:
public static Expression<Func<EntityA, bool>> HasId(int id)
{
return p => p.Id == id;
}
现在在查询我的 EntityB 时,我希望能够使用这个谓词以避免在 Expression<EntityB, bool>> (with p => p.EntityA.Id == id) 中重写它。
我想要类似的东西:
Expression<Func<EntityB, bool>> predicates = p => **initial condition on EntityB**
var myfunc = HasId(12).Compile();
predicates = predicates.And(p => myfunc(p.EntityA));
这种语法不起作用。
如何在Expression<Func<EntityB,bool>> 谓词中使用Expression<Func<EntityA, bool>>?
* 编辑 *
忘了提及我在我的项目中使用的是 Devforce(来自 Ideablade)。 谓词。And 来自它们(我最初以为我来自系统)。
错误信息是:
未知表达式类型:Invoke(value(UserQuery+c__DisplayClass1).myfunc , p.EntityA)
堆栈跟踪是:
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressionCore(Expression e)
à IdeaBlade.Linq.TransformExpressionVisitor.VisitExpressionCore(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpression(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressionCore(Expression e)
à IdeaBlade.Linq.TransformExpressionVisitor.VisitExpressionCore(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpression(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressionCore(Expression e)
à IdeaBlade.Linq.TransformExpressionVisitor.VisitExpressionCore(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpression(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressionCore(Expression e)
à IdeaBlade.Linq.TransformExpressionVisitor.VisitExpressionCore(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpression(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressionCore(Expression e)
à IdeaBlade.Linq.TransformExpressionVisitor.VisitExpressionCore(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpression(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.<VisitExpressions>b__0(Expression e)
à System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
à System.Linq.Buffer`1..ctor(IEnumerable`1 source)
à System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressions(IEnumerable`1 expressions)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpressionCore(Expression e)
à IdeaBlade.Linq.TransformExpressionVisitor.VisitExpressionCore(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.VisitExpression(Expression expr)
à IdeaBlade.Linq.ExpressionVisitor.Visit(Expression expr)
à IdeaBlade.EntityModel.EntityQuery`1.ProcessExpression(Expression e)
à IdeaBlade.EntityModel.EntityQuery`1..ctor(Expression expression, IQueryable queryable)
à IdeaBlade.EntityModel.EntityQuery`1.System.Linq.IQueryProvider.CreateQuery[TElement](Expression expression)
à System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)
à IdeaBlade.EntityModel.EntityQueryExtensions.Where[TSource](IEntityQuery`1 source1, Expression`1 predicate)
【问题讨论】:
-
您说“此语法不起作用”,但您遇到了什么错误?
-
他可能正在使用 LinqKit - 其中包括表达式的扩展方法。
-
我注意到你做了
predicates.And(...)。你想在那里做什么?请注意,有一个 static 方法Expression.And(Expression, Expression)(MSDN)。但是,它的语法需要 两个 表达式参数(@Mike,或者他可能正在使用 LinqKit...) -
已编辑,实际上我使用的是 Ideablade 的 Devforce。助手“And”是由他们提供的,尽管它在 c# 库中很常见。我想要实现的是组合多个 Expression
> 而一些针对查询的主要实体,而另一些则针对一些导航属性 -
DevForce 不支持 Invoke,因为它在将表达式树序列化到服务器时无法序列化函数调用。尽管您可能无法使用现有的谓词,但 DevForce 中的其他一些动态查询功能可能仍然有帮助 - 请查看 PredicateBuilder 和 PredicateDescription here。
标签: c# lambda expression-trees devforce