1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
| <span>public</span> <span>class</span><span> ResolveExpression { </span><span>public</span> Dictionary<<span>string</span>, <span>object</span>><span> Argument; </span><span>public</span> <span>string</span><span> SqlWhere; </span><span>public</span><span> SqlParameter[] Paras; </span><span>private</span> <span>int</span> index = <span>0</span><span>; </span><span>///</span> <span><summary></span> <span>///</span><span> 解析lamdba,生成Sql查询条件 </span><span>///</span> <span></summary></span> <span>///</span> <span><param name="expression"></param></span> <span>///</span> <span><returns></returns></span> <span>public</span> <span>void</span><span> ResolveToSql(Expression expression) { </span><span>this</span>.index = <span>0</span><span>; </span><span>this</span>.Argument = <span>new</span> Dictionary<<span>string</span>, <span>object</span>><span>(); </span><span>this</span>.SqlWhere =<span> Resolve(expression); </span><span>this</span>.Paras = Argument.Select(x => <span>new</span><span> SqlParameter(x.Key, x.Value)).ToArray(); }
</span><span>private</span> <span>object</span><span> GetValue(Expression expression) { </span><span>if</span> (expression <span>is</span><span> ConstantExpression) </span><span>return</span> (expression <span>as</span><span> ConstantExpression).Value; </span><span>if</span> (expression <span>is</span><span> UnaryExpression) { UnaryExpression unary </span>= expression <span>as</span><span> UnaryExpression; LambdaExpression lambda </span>=<span> Expression.Lambda(unary.Operand); Delegate fn </span>=<span> lambda.Compile(); </span><span>return</span> fn.DynamicInvoke(<span>null</span><span>); } </span><span>if</span> (expression <span>is</span><span> MemberExpression) { MemberExpression member </span>= expression <span>as</span><span> MemberExpression; </span><span>string</span> name =<span> member.Member.Name; </span><span>var</span> constant = member.Expression <span>as</span><span> ConstantExpression; </span><span>if</span> (constant == <span>null</span><span>) </span><span>throw</span> <span>new</span> Exception(<span>"</span><span>取值时发生异常</span><span>"</span> +<span> member); </span><span>return</span> constant.Value.GetType().GetFields().First(x => x.Name ==<span> name).GetValue(constant.Value); } </span><span>throw</span> <span>new</span> Exception(<span>"</span><span>无法获取值</span><span>"</span> +<span> expression); }
</span><span>private</span> <span>string</span><span> Resolve(Expression expression) { </span><span>if</span> (expression <span>is</span><span> LambdaExpression) { LambdaExpression lambda </span>= expression <span>as</span><span> LambdaExpression; expression </span>=<span> lambda.Body; </span><span>return</span><span> Resolve(expression); } </span><span>if</span> (expression <span>is</span> BinaryExpression)<span>//</span><span>解析二元运算符</span> <span> { BinaryExpression binary </span>= expression <span>as</span><span> BinaryExpression; </span><span>if</span> (binary.Left <span>is</span><span> MemberExpression) { </span><span>object</span> value =<span> GetValue(binary.Right); </span><span>return</span><span> ResolveFunc(binary.Left, value, binary.NodeType); } </span><span>if</span> (binary.Left <span>is</span> MethodCallExpression && (binary.Right <span>is</span> UnaryExpression || binary.Right <span>is</span><span> MemberExpression)) { </span><span>object</span> value =<span> GetValue(binary.Right); </span><span>return</span><span> ResolveLinqToObject(binary.Left, value, binary.NodeType); } } </span><span>if</span> (expression <span>is</span> UnaryExpression)<span>//</span><span>解析一元运算符</span> <span> { UnaryExpression unary </span>= expression <span>as</span><span> UnaryExpression; </span><span>if</span> (unary.Operand <span>is</span><span> MethodCallExpression) { </span><span>return</span> ResolveLinqToObject(unary.Operand, <span>false</span><span>); } </span><span>if</span> (unary.Operand <span>is</span><span> MemberExpression) { </span><span>return</span> ResolveFunc(unary.Operand, <span>false</span><span>, ExpressionType.Equal); } } </span><span>if</span> (expression <span>is</span> MethodCallExpression)<span>//</span><span>解析扩展方法</span> <span> { </span><span>return</span> ResolveLinqToObject(expression, <span>true</span><span>); } </span><span>if</span> (expression <span>is</span> MemberExpression)<span>//</span><span>解析属性。。如x.Deletion</span> <span> { </span><span>return</span> ResolveFunc(expression, <span>true</span><span>, ExpressionType.Equal); } </span><span>var</span> body = expression <span>as</span><span> BinaryExpression; </span><span>if</span> (body == <span>null</span><span>) </span><span>throw</span> <span>new</span> Exception(<span>"</span><span>无法解析</span><span>"</span> +<span> expression); </span><span>var</span> Operator =<span> GetOperator(body.NodeType); </span><span>var</span> Left =<span> Resolve(body.Left); </span><span>var</span> Right =<span> Resolve(body.Right); </span><span>string</span> Result = <span>string</span>.Format(<span>"</span><span>({0} {1} {2})</span><span>"</span><span>, Left, Operator, Right); </span><span>return</span><span> Result; }
</span><span>///</span> <span><summary></span> <span>///</span><span> 根据条件生成对应的sql查询操作符 </span><span>///</span> <span></summary></span> <span>///</span> <span><param name="expressiontype"></param></span> <span>///</span> <span><returns></returns></span> <span>private</span> <span>string</span><span> GetOperator(ExpressionType expressiontype) { </span><span>switch</span><span> (expressiontype) { </span><span>case</span><span> ExpressionType.And: </span><span>return</span> <span>"</span><span>and</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.AndAlso: </span><span>return</span> <span>"</span><span>and</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.Or: </span><span>return</span> <span>"</span><span>or</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.OrElse: </span><span>return</span> <span>"</span><span>or</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.Equal: </span><span>return</span> <span>"</span><span>=</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.NotEqual: </span><span>return</span> <span>"</span><span><></span><span>"</span><span>; </span><span>case</span><span> ExpressionType.LessThan: </span><span>return</span> <span>"</span><span><</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.LessThanOrEqual: </span><span>return</span> <span>"</span><span><=</span><span>"</span><span>; </span><span>case</span><span> ExpressionType.GreaterThan: </span><span>return</span> <span>"</span><span>></span><span>"</span><span>; </span><span>case</span><span> ExpressionType.GreaterThanOrEqual: </span><span>return</span> <span>"</span><span>>=</span><span>"</span><span>; </span><span>default</span><span>: </span><span>throw</span> <span>new</span> Exception(<span>string</span>.Format(<span>"</span><span>不支持{0}此种运算符查找!</span><span>"</span> +<span> expressiontype)); } }
</span><span>private</span> <span>string</span> ResolveFunc(Expression left, <span>object</span><span> value, ExpressionType expressiontype) { </span><span>string</span> Name = (left <span>as</span><span> MemberExpression).Member.Name; </span><span>string</span> Operator =<span> GetOperator(expressiontype); </span><span>string</span> Value =<span> value.ToString(); </span><span>string</span> CompName =<span> SetArgument(Name, Value); </span><span>string</span> Result = <span>string</span>.Format(<span>"</span><span>({0} {1} {2})</span><span>"</span><span>, Name, Operator, CompName); </span><span>return</span><span> Result; }
</span><span>private</span> <span>string</span> ResolveLinqToObject(Expression expression, <span>object</span> value, ExpressionType? expressiontype = <span>null</span><span>) { </span><span>var</span> MethodCall = expression <span>as</span><span> MethodCallExpression; </span><span>var</span> MethodName =<span> MethodCall.Method.Name; </span><span>switch</span> (MethodName)<span>//</span><span>这里其实还可以改成反射调用,不用写switch</span> <span> { </span><span>case</span> <span>"</span><span>Contains</span><span>"</span><span>: </span><span>if</span> (MethodCall.Object != <span>null</span><span>) </span><span>return</span><span> Like(MethodCall); </span><span>return</span><span> In(MethodCall, value); </span><span>case</span> <span>"</span><span>Count</span><span>"</span><span>: </span><span>return</span><span> Len(MethodCall, value, expressiontype.Value); </span><span>case</span> <span>"</span><span>LongCount</span><span>"</span><span>: </span><span>return</span><span> Len(MethodCall, value, expressiontype.Value); </span><span>default</span><span>: </span><span>throw</span> <span>new</span> Exception(<span>string</span>.Format(<span>"</span><span>不支持{0}方法的查找!</span><span>"</span><span>, MethodName)); } }
</span><span>private</span> <span>string</span> SetArgument(<span>string</span> name, <span>string</span><span> value) { name </span>= <span>"</span><span>@</span><span>"</span> +<span> name; </span><span>string</span> temp =<span> name; </span><span>while</span><span> (Argument.ContainsKey(temp)) { temp </span>= name +<span> index; index </span>= index + <span>1</span><span>; } Argument[temp] </span>=<span> value; </span><span>return</span><span> temp; }
</span><span>private</span> <span>string</span> In(MethodCallExpression expression, <span>object</span><span> isTrue) { </span><span>var</span> Argument1 = expression.Arguments[<span>0</span><span>]; </span><span>var</span> Argument2 = expression.Arguments[<span>1</span>] <span>as</span><span> MemberExpression; </span><span>var</span> fieldValue =<span> GetValue(Argument1); </span><span>object</span>[] array = fieldValue <span>as</span> <span>object</span><span>[]; List</span><<span>string</span>> SetInPara = <span>new</span> List<<span>string</span>><span>(); </span><span>for</span> (<span>int</span> i = <span>0</span>; i < array.Length; i++<span>) { </span><span>string</span> Name_para = <span>"</span><span>InParameter</span><span>"</span> +<span> i; </span><span>string</span> Value =<span> array[i].ToString(); </span><span>string</span> Key =<span> SetArgument(Name_para, Value); SetInPara.Add(Key); } </span><span>string</span> Name =<span> Argument2.Member.Name; </span><span>string</span> Operator = Convert.ToBoolean(isTrue) ? <span>"</span><span>in</span><span>"</span> : <span>"</span><span> not in</span><span>"</span><span>; </span><span>string</span> CompName = <span>string</span>.Join(<span>"</span><span>,</span><span>"</span><span>, SetInPara); </span><span>string</span> Result = <span>string</span>.Format(<span>"</span><span>{0} {1} ({2})</span><span>"</span><span>, Name, Operator, CompName); </span><span>return</span><span> Result; }
</span><span>private</span> <span>string</span><span> Like(MethodCallExpression expression) { Expression argument </span>= expression.Arguments[<span>0</span><span>]; </span><span>object</span> Temp_Vale =<span> GetValue(argument); </span><span>string</span> Value = <span>string</span>.Format(<span>"</span><span>%{0}%</span><span>"</span><span>, Temp_Vale); </span><span>string</span> Name = (expression.Object <span>as</span><span> MemberExpression).Member.Name; </span><span>string</span> CompName =<span> SetArgument(Name, Value); </span><span>string</span> Result = <span>string</span>.Format(<span>"</span><span>{0} like {1}</span><span>"</span><span>, Name, CompName); </span><span>return</span><span> Result; }
</span><span>private</span> <span>string</span> Len(MethodCallExpression expression, <span>object</span><span> value, ExpressionType expressiontype) { </span><span>object</span> Name = (expression.Arguments[<span>0</span>] <span>as</span><span> MemberExpression).Member.Name; </span><span>string</span> Operator =<span> GetOperator(expressiontype); </span><span>string</span> CompName =<span> SetArgument(Name.ToString(), value.ToString()); </span><span>string</span> Result = <span>string</span>.Format(<span>"</span><span>len({0}){1}{2}</span><span>"</span><span>, Name, Operator, CompName); </span><span>return</span><span> Result; }
}</span>
|