0

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

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 => 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 表达式

4

1 回答 1

0

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

    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;
    }
于 2013-07-05T07:44:41.000 回答