如何将表达式树转换为字典?
例如:
class Dummy
{
public int Id { get; set; }
public string Name { get; set; }
}
示例1:
MyStaticClass.ParseExpression<Dummy>(t => t.Id == 2)
//Result is dictionary with item:
<key, value>Id,2
示例2:
var s = "Foo";
MyStaticClass.ParseExpression<Dummy>(t => t.Id == 2 && t.Name == s)
//Result is dictionary with items:
<key, value>Id,2
<key, value>Name,"Foo"
我知道EF Core可以做到这一点,但不知道如何实现,因此我难以解析源代码。
我应该说表达式不包含||
和()
。
例如:
MyStaticClass.ParseExpression<Dummy>(t => t.Id == 2 || t.Id == 3)
或
MyStaticClass.ParseExpression<Dummy>(t => t.Id == 2 && (Name == "Foo" || Id Name == "Test")
答案 0 :(得分:2)
如果您确定表达式将仅采用提供的格式-您可以执行以下操作:
public class Dummy
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public class ExpressionConverter
{
public static Dictionary<string, string> Convert<T>(Expression<Func<T,bool>> expression)
{
var result = new Dictionary<string,string>();
var current = (BinaryExpression)expression.Body;
while (current.NodeType != ExpressionType.Equal)
{
ParseEquals((BinaryExpression)current.Right);
current = (BinaryExpression)current.Left;
}
ParseEquals(current);
void ParseEquals(BinaryExpression e)
{
var key = (MemberExpression) e.Left;
var value = (ConstantExpression) e.Right;
result.Add(key.Member.Name, value.Value.ToString());
}
return result;
}
}
用法:
var test = ExpressionConverter.Convert<Dummy>(x => x.Id == 5 && x.Name == "dummy" && x.Age == 11);
或替换ParseEquals
:
void ParseEquals(BinaryExpression e)
{
var key = (MemberExpression) e.Left;
object value;
switch (e.Right)
{
case ConstantExpression constantExpression:
value = constantExpression.Value;
break;
case MemberExpression memberExpression:
var obj = ((ConstantExpression)memberExpression.Expression).Value;
value = obj.GetType().GetField(memberExpression.Member.Name).GetValue(obj);
break;
default:
throw new UnknownSwitchValueException(e.Right.Type);
}
result.Add(key.Member.Name, value);
}
支持:
var myVar = "dummy";
var test = ExpressionConverter.Convert<Dummy>(x => x.Id == 5 && x.Name == myVar && x.Age == 11);