C# 迭代&;之间的每个参数&;或者| |在一个表达式中<;Func<;T、 布尔>&燃气轮机;Lambda表达式

C# 迭代&;之间的每个参数&;或者| |在一个表达式中<;Func<;T、 布尔>&燃气轮机;Lambda表达式,c#,generics,lambda,expression,func,C#,Generics,Lambda,Expression,Func,我想要一个类似于LINQ to SQLWhere方法的方法 db.Where(r => r.Age == 42 && r.Name = "Joe"); 我想采取以下措施: Something something = Get<Something>() .FilterBy(x => x.PropOne == 123 && x.PropTwo == 456); 当部分表达式与&&或| |组合时,如何访问每个表达式参数?示例代码 下面

我想要一个类似于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);
当部分表达式与
&&
| |
组合时,如何访问每个表达式参数?

示例代码 下面是一个如何获取
&&
的示例:

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;
    }
}
公共静态类筛选器扩展
{
公共阶级状况
{
公共字符串名称{get;set;}
公共字符串值{get;set;}
公共字符串运算符{get;set;}
}
公共静态T过滤器by(此T某物,表达式e)
{
var条件=新列表();
二进制表达式二进制表达式=
(二进制表达式)((一元表达式)e.Body).操作数;
检查条件(条件,二进制表达式);
return(T)Convert.ChangeType(test,typeof(T));
}
私有静态无效检查条件(列表条件,BinaryExpression BinaryExpression)
{
if(binaryExpression.NodeType==ExpressionType.AndAlso)
{
CheckConditions(conditions,binaryExpression.Left as binaryExpression);
CheckConditions(conditions,binaryExpression.Right as binaryExpression);
}
其他的
{
Add(GetCondition(binaryExpression));
}
}
私有静态条件GetCondition(BinaryExpression BinaryExpression)
{
var条件=新条件();
condition.Name=((MemberExpression)binaryExpression.Left).Member.Name;
condition.Value=binaryExpression
.Right.GetType().GetProperty(“值”)
.GetValue(binaryExpression.Right,null).ToString();
condition.Operator=binaryExpression.NodeType.ToString();
返回条件;
}
}
显然,
&&
的代码不完整;你应该有个主意

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

例如:
public static T FilterBy(这个列表中有一些东西,表达式e)

考虑 需要注意的是,可以将许多不同的表达式传递到此方法中,这些表达式将被编译,但会破坏您的方法

Something=Get().FilterBy(x=>123==x.PropOne)

Something=Get().FilterBy(x=>x.Method()==123)

Something-Something=Get().FilterBy(x=>(x.PropOne==123 | | x.PropOne==34)和&x.PropTwo==456)


确保验证表达式是否为您期望的类型。

问题在哪里?@MarcinJuraszek我想知道如何从方法(使用示例实现)访问每个表达式参数。表达式参数?对不起,还是不明白。也许其他人会更幸运。@MarcinJuraszek我想从内部分别访问
x.PropOne==123
x.PropTwo==456
。如果还不清楚,很抱歉。我想要一个操作与LINQ的Where方法类似的方法。@SBPhoenix-请检查我的编辑是否与您的问题匹配-尝试内联您的评论。这当然有帮助,非常感谢您的考虑和示例。我将如何迭代每个
&&
?我会使用一个
foreach
循环吗?如果是这样的话,你知道如何使用循环的一个例子吗?我改变了我的例子,展示了一个使用递归的基本实现。我还假设您希望捕获表达式的值,因此我将它们存储在一个列表中。这似乎就是您要找的吗?这正是我要找的,只是我似乎在
CheckConditions(conditions,binaryExpression.Left)
CheckConditions(conditions,binaryExpression.Right)
中得到了一个编译错误,说明
CheckConditions
是一个未知方法?我再次衷心感谢你的帮助!这正是我所需要的,就像一个符咒!非常感谢你的帮助。我一直在为此绞尽脑汁,因为我对一般的表达方式还不熟悉。
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));
}
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;
    }
}