Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何提取表达式的一部分_C#_Linq_Linq To Sql_Lambda_Expression - Fatal编程技术网

C# 如何提取表达式的一部分

C# 如何提取表达式的一部分,c#,linq,linq-to-sql,lambda,expression,C#,Linq,Linq To Sql,Lambda,Expression,我想简化代码来添加loadoptions和关联过滤,所以我创建了这个类 class GraphQuery<T> { private IQueryable<T> query; private DataLoadOptions load; public GraphQuery(DataLoadOptions load, IQueryable<T> query) { this.load = load; t

我想简化代码来添加loadoptions和关联过滤,所以我创建了这个类

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 ...
}
然而,我看到了一个非常简单的重复
e=>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;
    }
公共图形查询加载(表达式筛选器)
{
var expr=…提取表示关联属性的表达式的第一部分
load.LoadWith(expr);
加载。与(过滤器)关联;
归还这个;
}

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

我使用调试器查看可以从表达式中获得什么,并发现提取所需内容相当简单。我想这并不漂亮,但它完成了任务。如果有人对此有一些改进建议,请发表评论

    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;
    }
    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;
    }