从现有表达式在父对象上创建表达式树以进行 C# mongodb 驱动程序解析
Create expression tree on parent object from existing expression for c# mongodb driver parsing
我有一个这样的 class :
public class Person
{
public string Name { get; set; }
public string Email { get; set; }
// ...
}
我还有一个通用的 class,例如:
public class MyParentObject<T>
{
public T Item { get; set; }
// ...
}
例如,我有一个这样的表达式:
Expression<Func<Person, bool>> expression = p => p.Name == "MyName" && p.Email = "example@test.com"
如何将此表达式转换为:
Expression<Func<MyParentObject<Person>, bool>> expression = p => p.Item.Name == "MyName" && p.Item.Email = "example@test.com"
编辑:
我觉得我的问题还不够深入,我想要这样的方法:
public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression(Expression<Func<T, bool>> expression)
{
Expression <Func<MyParentObject<T>, bool>> result = // process...
// ...
return result;
}
编辑:
我必须创建一个新的树表达式,然后由 c# mongodb 驱动程序解析。我无法在表达式树上使用 Invoke 其他 Compile 方法。
我想我必须使用 ExpressionVisitor 但我不知道如何...
你可以像这样使用 Expression.Invoke
public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression)
{
Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item;
var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(
Expression.Invoke(expression, item.Body), item.Parameters);
return result;
}
更新: 另一种需要更多代码但消除了 Expression.Invoke
的方法是使用 ExpressionVisitor 派生的 class 来像这样替换传递的表达式的参数
public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression)
{
Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item;
var body = new ParameterExpressionReplacer { source = expression.Parameters[0], target = item.Body }.Visit(expression.Body);
var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(body, item.Parameters);
return result;
}
class ParameterExpressionReplacer : ExpressionVisitor
{
public ParameterExpression source;
public Expression target;
protected override Expression VisitParameter(ParameterExpression node)
{
return node == source ? target : base.VisitParameter(node);
}
}
我有一个这样的 class :
public class Person
{
public string Name { get; set; }
public string Email { get; set; }
// ...
}
我还有一个通用的 class,例如:
public class MyParentObject<T>
{
public T Item { get; set; }
// ...
}
例如,我有一个这样的表达式:
Expression<Func<Person, bool>> expression = p => p.Name == "MyName" && p.Email = "example@test.com"
如何将此表达式转换为:
Expression<Func<MyParentObject<Person>, bool>> expression = p => p.Item.Name == "MyName" && p.Item.Email = "example@test.com"
编辑:
我觉得我的问题还不够深入,我想要这样的方法:
public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression(Expression<Func<T, bool>> expression)
{
Expression <Func<MyParentObject<T>, bool>> result = // process...
// ...
return result;
}
编辑:
我必须创建一个新的树表达式,然后由 c# mongodb 驱动程序解析。我无法在表达式树上使用 Invoke 其他 Compile 方法。
我想我必须使用 ExpressionVisitor 但我不知道如何...
你可以像这样使用 Expression.Invoke
public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression)
{
Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item;
var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(
Expression.Invoke(expression, item.Body), item.Parameters);
return result;
}
更新: 另一种需要更多代码但消除了 Expression.Invoke
的方法是使用 ExpressionVisitor 派生的 class 来像这样替换传递的表达式的参数
public static Expression<Func<MyParentObject<T>, bool>> GetParentExpression<T>(Expression<Func<T, bool>> expression)
{
Expression<Func<MyParentObject<T>, T>> item = parent => parent.Item;
var body = new ParameterExpressionReplacer { source = expression.Parameters[0], target = item.Body }.Visit(expression.Body);
var result = Expression.Lambda<Func<MyParentObject<T>, bool>>(body, item.Parameters);
return result;
}
class ParameterExpressionReplacer : ExpressionVisitor
{
public ParameterExpression source;
public Expression target;
protected override Expression VisitParameter(ParameterExpression node)
{
return node == source ? target : base.VisitParameter(node);
}
}