迭代 && 或 || 之间的每个参数在一个表达式> lambda 表达式中

本文关键字:表达式 amp 一个 lambda func bool 之间 参数 迭代 | 更新日期: 2023-09-27 18:32:44

我想要一个类似于遵循 LINQ-to-SQL Where方法的方法。

 db.Where(r => r.Age == 42 && r.Name = "Joe");

我想实现:

Something something = Get<Something>()
    .FilterBy(x => x.PropOne == 123 && x.PropTwo == 456);

并使用如下所示的方法;能够访问每个表达式参数的 Left.Name运算符Right.Value 以执行工作。

public static T FilterBy<T>(this T something, Expression<Func<T, object>> e)
{
    // do work here
}

到目前为止,我可以使用以下方法解析像 x => x.PropOne == 123 这样的单个条件,而无需使用 &&&或 || 。

public static T FilterBy<T>(this T something, Expression<Func<T, object>> e)
{
    BinaryExpression binaryExpression = 
        (BinaryExpression)((UnaryExpression)e.Body).Operand;
    string left = ((MemberExpression)binaryExpression.Left).Member.Name;
    string right = binaryExpression
        .Right.GetType().GetProperty("Value")
        .GetValue(binaryExpression.Right).ToString();
    ExpressionType @operator = binaryExpression.NodeType;
    return (T)Convert.ChangeType(something, typeof(T));
}

当表达式部分与&&||组合时,如何访问每个表达式参数?

迭代 && 或 || 之间的每个参数在一个表达式<func<t,bool>> lambda 表达式中

示例代码

下面是如何获取&&的示例:

public static class FilterExtension
{
    public class Condition
    {
        public string Name { get; set; }
        public string Value { get; set; }
        public string Operator { get; set; }
    }
    public static T FilterBy<T>(this T something, Expression<Func<T, object>> e)
    {
        var conditions = new List<Condition>();
        BinaryExpression binaryExpression =
       (BinaryExpression)((UnaryExpression)e.Body).Operand;
        CheckConditions(conditions, binaryExpression);
        return (T)Convert.ChangeType(test, typeof(T));
    }
    private static void CheckConditions(List<Condition> conditions, BinaryExpression binaryExpression)
    {
        if (binaryExpression.NodeType == ExpressionType.AndAlso)
        {
            CheckConditions(conditions, binaryExpression.Left as BinaryExpression);
            CheckConditions(conditions, binaryExpression.Right as BinaryExpression);
        }
        else
        {
            conditions.Add(GetCondition(binaryExpression));
        }
    }
    private static Condition GetCondition(BinaryExpression binaryExpression)
    {
        var condition = new Condition();
        condition.Name = ((MemberExpression)binaryExpression.Left).Member.Name;
        condition.Value = binaryExpression
            .Right.GetType().GetProperty("Value")
            .GetValue(binaryExpression.Right, null).ToString();
        condition.Operator = binaryExpression.NodeType.ToString();
        return condition;
    }
}

显然,&&的代码并不完整;你应该得到一个想法。

另外,我注意到您传入了一个类型为 T 的对象。如果这像 Linq-To-SQL 一样工作,它可能应该是某种列表或可枚举的。

例: public static T FilterBy<T>(this List<T> something, Expression<Func<T, object>> e)

考虑

请注意,可以将许多不同的表达式传递到此方法中,这些表达式将编译但会破坏您的方法。

Something something = Get<Something>().FilterBy(x => 123 == x.PropOne);

Something something = Get<Something>().FilterBy(x => x.Method() == 123);

Something something = Get<Something>().FilterBy(x => (x.PropOne == 123 || x.PropOne == 34) && x.PropTwo == 456 );

请确保验证表达式是否为预期类型。