C# 如何提取表达式的一部分
我想简化代码来添加loadoptions和关联过滤,所以我创建了这个类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
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;
}