【发布时间】:2020-03-10 22:18:00
【问题描述】:
我正在开发一个规则引擎,使用这种设计在数据库中设置规则:
“PropertyName”“Operator”“PropertyValue”(例如:data.employee.salary = 10000)。这是针对一个将数据作为属性的主类运行的,该类实际上指向一个名为 Data 的嵌套类,而“数据”内部类又具有一个名为 employee 的属性,该属性映射到一个 Employee 内部类,该类的属性为工资现在是字符串。
这是我使用 ExpressionTrees 编写的 RulesEngine 代码的一部分:
// Loop through each of the rules per Ruleset and compile them against the properties of the supplied T object.
//NOTE: The values in the database column 'PropertyName' should match exactly with the properties of the T class.
rules.ForEach(rule =>
{
var genericType = Expression.Parameter(typeof(T));
// var key = MemberExpression.Property(genericType, rule.PropertyName);
var key = CreateExpression(typeof(T), rule.PropertyName); //rule.PropertyName== 'data.employee.salary'
var propertyType = GetProp(typeof(T), rule.PropertyName).PropertyType; // System.String
var value = Expression.Constant(Convert.ChangeType(rule.PropertyValue, propertyType)); //"10000"
` if (rule.Operator != ExpressionType.Lambda && rule.Operator != ExpressionType.Default) //This covers both '=' and '<>' or anything Binary-ish Operators setup in the Rules table.
{
var binaryExpression = Expression.MakeBinary(rule.Operator, key, value);
compiledExpTreeRules.Add(Expression.Lambda<Func<T, bool>>(key, genericType).Compile());
}
static LambdaExpression CreateExpression(Type type, string propertyName)
{
var param = Expression.Parameter(type, "x");
Expression body = param;
foreach (var member in propertyName.Split('.'))
{
body = Expression.PropertyOrField(body, member);
}
return Expression.Lambda(body, param);
//return MemberExpression.Property(body, propertyName);
}
我遇到的问题是我从我的 CreateExpression() 方法返回一个 Expression.Lambda。我必须编写这个方法,因为我的 T 输入类中有嵌套类,因此属性和规则可以在数据库中配置,在最内层嵌套类的叶属性级别。
当我尝试执行这一行时,它给了我一个错误:
var binaryExpression = Expression.MakeBinary(rule.Operator, key, value);
当我已经知道 Lambda 表达式(即“key”参数)时,如何制作二进制表达式? MakeBinary 参数列表中的那个键出错了。我也尝试过 key.body,但我只是不知道如何 1) 使 CreateExpression() 返回 MemberExpression.Property 或 2) 当它返回 x=>x.innnerclass1.prop1 类型的 lambda 表达式时,我该怎么做将其用作“键”并制作 BinaryExpression?我有 lambda,我有运算符(来自 db),我有值,但我正在努力用它构建一个 BinaryExpression。
提前致谢!
【问题讨论】:
-
这个问题有点混乱。你能先说说你遇到了什么错误吗?
标签: c# linq expression-trees rules