【问题标题】:how to extracting a part of an expression如何提取表达式的一部分
【发布时间】:2013-05-30 11:02:00
【问题描述】:

我想简化代码以添加加载选项和关联过滤,所以我创建了这个类。

class GraphQuery<T>
{
    private IQueryable<T> query;
    private DataLoadOptions load;

    public GraphQuery(DataLoadOptions load, IQueryable<T> query)
    {
        this.load = load;
        this.query = query;
    }

    public GraphQuery<T> Load(
            Expression<Func<T, object>> expr, 
            Expression<Func<T, object>> filter)
    {
        load.LoadWith(expr);
        load.AssociateWith(filter);
        return this;
    }

    // more public methods ...
}

然后可以这样使用:

var clients = Graph(db.Clients.Where(e => !e.Deleted))
    .Load(e => e.ClientPersons, 
        e => e.ClientPersons.Where(j => !j.Person.Deleted));

但是,我看到 e =&gt; e.ClientPersons 的一个非常简单的重复。所以我想将上述用法减少到:

var clients = Graph(db.Clients.Where(e => !e.Deleted))
    .Load(e => e.ClientPersons.Where(j => !j.Person.Deleted));

所以 Load 函数应该看起来像

    public GraphQuery<T> Load(Expression<Func<T, object>> filter)
    {
        var expr = ... extract first part of the expression that represents the association property
        load.LoadWith(expr);
        load.AssociateWith(filter);
        return this;
    }

除了在查询中使用之外,我从未使用过 linq 表达式

【问题讨论】:

    标签: c# linq linq-to-sql lambda expression


    【解决方案1】:

    我使用调试器查看了我可以从表达式中得到什么,发现提取我需要的内容相当简单。我想它不漂亮,但它完成了工作。如果有人有一些改进建议 - 请发表评论。

        private static LambdaExpression GetRootMemberExpression(LambdaExpression lambda1)
        {
            var expr = lambda1.Body;
            while (!FindRoot(ref expr)) ;
            if (!(expr is MemberExpression))
                throw new Exception("MemberExpression required");
            return Expression.Lambda(expr, (expr as MemberExpression).Expression as ParameterExpression);
        }
    
    
        private static bool FindRoot(ref Expression expr)
        {
            if (expr is MemberExpression)
                return FindRoot(ref expr, (expr as MemberExpression).Expression);
            if (expr.NodeType == ExpressionType.Call)
                return FindRoot(ref expr, (expr as MethodCallExpression).Object);
            throw new Exception("Unexpected Expression type encountered (" + expr.NodeType + ")");
        }
    
        private static bool FindRoot(ref Expression expr, Expression expr2)
        {
            if (expr2.NodeType == ExpressionType.Parameter)
                return true;
            expr = expr2;
            return false;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-22
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-25
      相关资源
      最近更新 更多