【问题标题】:Linq Expression to execute existing expression on a child property用于在子属性上执行现有表达式的 Linq 表达式
【发布时间】:2012-07-05 18:33:52
【问题描述】:

这是一个简单的类

public class Parent
{
    public Child Child { get; set; }
}

这是我正在尝试实现的方法

Expression<Func<Parent, long>> GetChildIDExpr(Expression<Func<Child, long>> objectIdExpr)
{
    //So I need to return an expression that can accept a Parent
    //and apply the given expression to its Child property.
}

听起来很简单,但我就是想不通!

我该如何实现这个方法?

编辑:

我正在使用 LINQ to Entities,所以调用 Expression.Invoke 不起作用。

【问题讨论】:

  • 执行现有表达式是指像“parents.whereChild(express)”这样的过滤器吗?
  • 基本上,说objectIdExpr = obj =&gt; obj.ID,我需要一种实体方式来做p =&gt; objectIdExpr.Invoke(p.Child)
  • 检查我的答案,@SPFiredrake 是正确的,我的答案与一个不错的库中的想法相同

标签: c# linq linq-to-entities expression-trees


【解决方案1】:

你可以使用 LinqKit http://www.albahari.com/nutshell/linqkit.aspx 使用AsExpandable()Compile()/Invoke(),它将内联外部表达式,允许在Linq-to-sql 或Linq-to-entities 中使用

【讨论】:

  • 这可能是最安全的方法,因为它允许正确组合表达式树。 +1
【解决方案2】:

最终,您似乎想要组合表达式。但问题在于:表达式树是不可变的,它们将保持其参数引用,这使得将它们链接在一起变得困难。然而,这并不是说它不能完成(或者不是太难)。但是,您需要 ExpressionVisitor 的帮助,这将交换父参数引用和子参数引用。

class SwapVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public SwapVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
         return node == from ? to : base.Visit(node);
    }
}

然后你可以在你的GetChildIDExpr 中将它们链接在一起:

Expression<Func<Parent, long>> GetChildIDExpr(Expression<Func<Child, long>> objectIdExpr)
{
    Expression<Func<Parent, Child>> parentEX = p => p.Child;
    var swap = new SwapVisitor(objectIdExpr.Parameters[0], parentEX.Body);
    var newExpr = Expression.Lambda<Func<Parent, long>>(
           swap.Visit(objectIdExpr.Body), parentEX.Parameters);
    return newExpr;
}

试试看,然后告诉我们。

【讨论】:

  • 这是一个很好的解决方案,但是改变'swap.Visit(parentEX.Body), objectIdExpr.Parameters);' to 'swap.Visit(objectIdExpr.Body), parentEX.Parameters);'
  • 谢谢@BalazsTihanyi,我在我的测试项目中做对了,但不是在这里。哦!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多