gpt4 book ai didi

c# - 如何在没有调用的情况下合并两个 C# Lambda 表达式?

转载 作者:可可西里 更新时间:2023-11-01 08:18:39 24 4
gpt4 key购买 nike

我想合并以下表达式:

// example class
class Order
{
List<OrderLine> Lines
}
class OrderLine { }

Expression<Func<Order, List<OrderLine>>> selectOrderLines = o => o.Lines;
Expression<Func<List<OrderLine>, Boolean>> validateOrderLines = lines => lines.Count > 0;

// now combine those to
Expression<Func<Order, Boolean>> validateOrder;

我使用对 selectOrderLines 的调用并将结果提供给 validateOrderLines 使其工作,但因为我在 Entity Framework 中使用这些表达式,所以我实际上必须创建一个干净的表达式,它应该表示:

Expression<Func<Order, Boolean>> validateOrder = o => o.Lines.Count > 0;

我该怎么做?

最佳答案

最优雅的方法是使用 Expression Visitor .特别是这个 MSDN Blog Entry描述了如何在不调用的情况下使用它来组合谓词(使用 bool 值 And 或 Or)。

已编辑 意识到 bool 组合不是你想要的,我写了一个 ExpressionVisitor 的示例用法来解决你的特定问题:

public class ParameterToMemberExpressionRebinder : ExpressionVisitor
{
ParameterExpression _paramExpr;
MemberExpression _memberExpr;

ParameterToMemberExpressionRebinder(ParameterExpression paramExpr, MemberExpression memberExpr)
{
_paramExpr = paramExpr;
_memberExpr = memberExpr;
}

protected override Expression Visit(Expression p)
{
return base.Visit(p == _paramExpr ? _memberExpr : p);
}

public static Expression<Func<T, bool>> CombinePropertySelectorWithPredicate<T, T2>(
Expression<Func<T, T2>> propertySelector,
Expression<Func<T2, bool>> propertyPredicate)
{
var memberExpression = propertySelector.Body as MemberExpression;

if (memberExpression == null)
{
throw new ArgumentException("propertySelector");
}

var expr = Expression.Lambda<Func<T, bool>>(propertyPredicate.Body, propertySelector.Parameters);
var rebinder = new ParameterToMemberExpressionRebinder(propertyPredicate.Parameters[0], memberExpression);
expr = (Expression<Func<T, bool>>)rebinder.Visit(expr);

return expr;
}

class OrderLine
{
}

class Order
{
public List<OrderLine> Lines;
}

static void test()
{
Expression<Func<Order, List<OrderLine>>> selectOrderLines = o => o.Lines;
Expression<Func<List<OrderLine>, Boolean>> validateOrderLines = lines => lines.Count > 0;
var validateOrder = ParameterToMemberExpressionRebinder.CombinePropertySelectorWithPredicate(selectOrderLines, validateOrderLines);

// validateOrder: {o => (o.Lines.Count > 0)}
}
}

关于c# - 如何在没有调用的情况下合并两个 C# Lambda 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1131869/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com