C# 迭代&;之间的每个参数&;或者| |在一个表达式中<;Func<;T、 布尔>&燃气轮机;Lambda表达式
我想要一个类似于LINQ to SQLC# 迭代&;之间的每个参数&;或者| |在一个表达式中<;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); 当部分表达式与&&或| |组合时,如何访问每个表达式参数?示例代码 下面
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;
}
}