数据库实体映射经常需要把lamda表达式转换为sql表达式,可以通过Expression<Tdelegate>来解析,下面是一个条件表达式解析类,还有很多不完善的,只是提供一种比较简单易懂的思路。
1 internal class PredicateConvert<T>
2 {
3 public string PredicateText { get; private set; }
4 Dictionary<PropertyInfo, ColumnAttribute> _columns;
5 public PredicateConvert(Expression<T>predicate,Dictionary<PropertyInfo,ColumnAttribute>columns)
6 {
7 _columns = columns;
8 var expression = predicate.Body;
9 if (expression is BinaryExpression)
10 {
11 PredicateText = BinaryConvert((BinaryExpression)expression);
12 }
13 else if (expression .NodeType == ExpressionType.IsTrue)
14 {
15 PredicateText = "";
16 }
17 else
18 {
19 throw new ArgumentException("Invalid lambda expression");
20 }
21 }
22 private string BinaryConvert(BinaryExpression expression)
23 {
24 //body
25 string text = string.Empty;
26 switch (expression.NodeType)
27 {
28 case ExpressionType.AndAlso:
29 text = " and ";
30 break;
31 case ExpressionType.OrElse:
32 text = " or ";
33 break;
34 case ExpressionType.Equal:
35 text = " == ";
36 break;
37 case ExpressionType.NotEqual:
38 text = " != ";
39 break;
40 case ExpressionType.GreaterThanOrEqual:
41 text = " >= ";
42 break;
43 case ExpressionType.GreaterThan:
44 text = " > ";
45 break;
46 case ExpressionType.LessThanOrEqual:
47 text = " <= ";
48 break;
49 case ExpressionType.LessThan:
50 text = " < ";
51 break;
52 default:
53 throw new ArgumentException("Invalid lambda expression");
54 }
55 //left
56 var lefttext = string.Empty;
57 var left = expression.Left;
58 if (left is BinaryExpression)
59 {
60 lefttext = BinaryConvert((BinaryExpression)left);
61 }
62 else if(left is MemberExpression)
63 {
64 lefttext = MemberConvert((MemberExpression)left);
65 }
66 else if (left is ConstantExpression)
67 {
68 lefttext = ConstantConvert((ConstantExpression)left);
69 }
70 else
71 {
72 throw new ArgumentException("Invalid lambda expression");
73 }
74 //right
75 var righttext = string.Empty;
76 var right = expression.Right;
77 if (right is BinaryExpression)
78 {
79 righttext = BinaryConvert((BinaryExpression)right);
80 }
81 else if (right is MemberExpression)
82 {
83 righttext = MemberConvert((MemberExpression)right);
84 }
85 else if (right is ConstantExpression)
86 {
87 righttext = ConstantConvert((ConstantExpression)right);
88 }
89 else
90 {
91 throw new ArgumentException("Invalid lambda expression");
92 }
93 return lefttext + text + righttext;
94 }
95 private string MemberConvert(MemberExpression expression)
96 {
97 var member = expression.Member as PropertyInfo;
98 if (member != null && _columns.ContainsKey(member))
99 {
100 return " " + _columns[member].Name + " ";
101 }
102 else
103 {
104 throw new ArgumentException("Invalid lambda expression");
105 }
106 }
107 private string ConstantConvert(ConstantExpression expression)
108 {
109 if (expression.Type == typeof(string))
110 {
111 return " '" + expression.Value + "' ";
112 }
113 else
114 {
115 return " " + expression.Value.ToString() + " ";
116 }
117 }
118 }
下面是调用例子:
1 class Person
2 {
3 public int Id{get;set;}
4 public string Name{get;set;}
5 }
6
7
8 public void test8()
9 {
10 Table<Person> table = new Table<Person>();
11 PredicateConvert<Func<Person, bool>> predicate = new PredicateConvert<Func<Person, bool>>(p => p.Id > 10 && p.Id < 100,table.Columns);
12 Trace.WriteLine(predicate.PredicateText);
13 }