簡體   English   中英

如何從 Lambda 表達式中獲取表達式

[英]How to get an Expression from a Lambda Expression

我正在開發一個規則引擎,其中的規則是通過這種設計在數據庫中設置的:

"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。

提前致謝!

這個問題有點令人困惑,但聽起來您手頭有三件事:

  • 帶有參數x和主體xip lambda 表達式lambda
  • 表達式value
  • 二元運算符類型——假設它是“加法”。

你想要的是為x => xip + value構造 lambda ,是嗎?

要做到這一點,你會說

// Given values:
LambdaExpression lambda = whatever;
Expression value = whatever;    
ExpressionType operator = whatever;
// Computed values:
Expression key = lambda.Body;
List<ParameterExpression> ps = lambda.Parameters;
BinaryExpression binop = Expression.MakeBinary(operator, key, value);
LambdaExpression newLambda = Expression.Lambda(binop, ps);

那有意義嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM