根据另一个 属性 c# 表达式树的值获取参数
get parameter base on value of another property c# expression tree
我有两个 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; }
}
这里我有一个字典,其中的键是 DLTypeRefs,值是不应为 null 的代码,例如在此示例中,如果 DLTypeRef 为 5,则 Code1 属性 应该具有值且不能为 null。
我想做的是从字典中动态获取不应为空的代码。
然后我想从 JoinedMapVoucher 类型获取该代码并检查它是否为空。
在下面的代码中,我写了评论,我想从字典中获取代码,然后从 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);
}
如何在 needCode 变量中动态获取 属性?
您需要构建一个 switch 语句,它将打开 getCode
值和 return 对应的 属性。沿着这条线:
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")
),
}
);
这应该代表在您的 lambda 中生成的沿着这条线的东西:
var code = dictionary[dlTypeRef];
switch (code)
{
case "Code1":
return JoinedMapVoucher.Code1;
case NullCode:
return JoinedMapVoucher.Code2;
default:
return "-1";
}
我有两个 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; }
}
这里我有一个字典,其中的键是 DLTypeRefs,值是不应为 null 的代码,例如在此示例中,如果 DLTypeRef 为 5,则 Code1 属性 应该具有值且不能为 null。 我想做的是从字典中动态获取不应为空的代码。 然后我想从 JoinedMapVoucher 类型获取该代码并检查它是否为空。 在下面的代码中,我写了评论,我想从字典中获取代码,然后从 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);
}
如何在 needCode 变量中动态获取 属性?
您需要构建一个 switch 语句,它将打开 getCode
值和 return 对应的 属性。沿着这条线:
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")
),
}
);
这应该代表在您的 lambda 中生成的沿着这条线的东西:
var code = dictionary[dlTypeRef];
switch (code)
{
case "Code1":
return JoinedMapVoucher.Code1;
case NullCode:
return JoinedMapVoucher.Code2;
default:
return "-1";
}