简体   繁体   English

根据另一个属性 c# 表达式树的值获取参数

[英]get parameter base on value of another property c# expression tree

i have two class:我有两个 class:

class JoinedMapVoucher
{
    public string Code1 { get; set; }
    public string Code2 { get; set; }
    public string Code3 { get; set; }
    public DL DL1 { get; set; }
    public DL DL2 { get; set; }
    public DL DL3 { get; set; }
    public DL DL4 { get; set; }
}
class DL
{
    public long DLTypeRef { get; set; }
}

here i have a dictionary which keys are DLTypeRefs and values are code that should not be null for example in this example if DLTypeRef is 5 then Code1 property should have value and can not be null.在这里,我有一个字典,其中键是 DLTypeRefs,值是不应该是 null 的代码,例如在本例中,如果 DLTypeRef 为 5,那么 Code1 属性应该具有值并且不能是 null。 what i want to do is i get code that should not be null dynamically from dictionary.我想做的是我从字典中动态获取不应该是 null 的代码。 and then i want to get that Code from JoinedMapVoucher type and check if it is null or not.然后我想从 JoinedMapVoucher 类型中获取该代码并检查它是否是 null 。 in code below i write comments where i want to get Code from dictionary and then get that property from JoinedMapVoucher parameter but it not work.在下面的代码中,我写了我想从字典中获取代码的注释,然后从 JoinedMapVoucher 参数中获取该属性,但它不起作用。

 var dic = new Dictionary<long, string>();
            dic.Add(5, "Code1");
            dic.Add(-1, "NullCode");
            var dicConst = Expression.Constant(dic);
    
            var list = Expression.Constant(new List<long> { 1, 2, 3, 4, 5 });
            var defaultDL = new DL { DLTypeRef = -1, Id = -1 };
            var foos = new List<JoinedMapVoucher> {new JoinedMapVoucher { DL2 = new DL { DLTypeRef = 5, Id = 55 } } }.AsQueryable();
            var containsMethod = typeof(List<long>).GetMethod(nameof(List<long>.Contains), new[] { typeof(long) });
    
            var parameter = Expression.Parameter(typeof(JoinedMapVoucher), "JoinedMapVoucher");
    
            for (var i = 1; i <= 4; i++)
            {
                
                var dl = Expression.PropertyOrField(parameter, "DL" + i.ToString());
                var actualDL = Expression.Coalesce(dl, Expression.Constant(defaultDL));
                var dlTypeRef = Expression.PropertyOrField(actualDL, "DLTypeRef");
                var or1 = Expression.Or(Expression.Equal(dlTypeRef, Expression.Constant((long)-1)), Expression.Not(Expression.Call(list, containsMethod, dlTypeRef)));
    
                
                var dicGetItemMethod = typeof(Dictionary<long, string>).GetMethod("get_Item", new[] { typeof(long) });
                var getCode = Expression.Constant(Expression.Call(dicConst, dicGetItemMethod, dlTypeRef)); **//here this call should return code from dictionary which it can be Code5 or NullCode**

               **var needCode=Expression.PropertyOrFeild(parameter,getCode) // then i want to get Code property from parameter dynamically**
                    
                
    
                var lambda = Expression.Lambda<Func<JoinedMapVoucher, bool>>(or1, new ParameterExpression[] { parameter });
                Console.WriteLine(lambda.Body);
                foos = foos.Where(lambda);
            }

how to get property dynamically in needCode variable?如何在需要代码变量中动态获取属性?

You need to build a switch statement which will switch on getCode value and return corresponding property.您需要构建一个 switch 语句,它将打开getCode值并返回相应的属性。 Something along this lines:沿着这条线的东西:

var getCode = Expression.Call(dicConst, dicGetItemMethod, dlTypeRef);
SwitchExpression switchExpr =
    Expression.Switch(
        getCode,
        Expression.Constant("-1"), // default case when none is matched
        new SwitchCase[]
        {
            Expression.SwitchCase( // switch case for "Code1" returned from dict
                Expression.PropertyOrField(parameter, nameof(JoinedMapVoucher.Code1)),
                Expression.Constant( nameof(JoinedMapVoucher.Code1))
            ),
            Expression.SwitchCase( // switch case for "NullCode" returned from dict
                Expression.PropertyOrField(parameter, nameof(JoinedMapVoucher.Code2)),
                Expression.Constant("NullCode")
            ),
            
        }
    );

Which should represent something along this lines generated in your lambda:这应该代表在您的 lambda 中生成的内容:

var code = dictionary[dlTypeRef];
switch (code)
{
     case "Code1":
         return JoinedMapVoucher.Code1;
     case NullCode:
         return JoinedMapVoucher.Code2;
     default:
         return "-1";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM