前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Lambda转sql部分代码保存

Lambda转sql部分代码保存

作者头像
蓝夏
发布2022-03-10 16:36:01
7740
发布2022-03-10 16:36:01
举报
文章被收录于专栏:bluesummer
代码语言:javascript
复制
  1     public class SqlExpressionTree
  2     {
  3         public string GetQuerySql<T>(Expression<Func<T, bool>> condi)
  4         {
  5             string condition = "select * from  "+typeof(T).Name+" "+ typeof(T).Name + " where ";
  6             BinaryExpression body = (BinaryExpression)condi.Body;
  7             condition+= GetSqlByExpression(body);
  8             return condition;
  9         }
 10         /// <summary>
 11         /// 通过Lambda解析为Sql
 12         /// </summary>
 13         /// <param name="func"></param>
 14         /// <returns></returns>
 15         public static string GetSqlByExpression(Expression func)
 16         {
 17             var funcType = CheckExpressionType(func);
 18             switch (funcType)
 19             {
 20                 case EnumNodeType.BinaryOperator:
 21                     return VisitBinaryExpression(func as BinaryExpression);
 22                 case EnumNodeType.Constant:
 23                     return VisitConstantExpression(func as ConstantExpression);
 24                 case EnumNodeType.Call:
 25                     return VisitMethodCallExpression(func as MethodCallExpression);
 26                 case EnumNodeType.UndryOperator:
 27                     return VisitUnaryExpression(func as UnaryExpression);
 28                 case EnumNodeType.MemberAccess:
 29                     return VisitMemberAccessExpression(func as MemberExpression);
 30                 default:
 31                     throw new NotSupportedException("不支持的操作在表达式处理中:");
 32             }
 33         }
 34         public string CheckExpression(Expression exp)
 35         {
 36             string leftClude = "", rightClude = "";
 37             if (exp.ToString().IndexOf("((") == 0)
 38             {
 39                 leftClude = "("; rightClude = ")";
 40             }
 41             if (exp.NodeType == ExpressionType.MemberAccess || exp.NodeType == ExpressionType.Constant)
 42             {
 43                 return exp.ToString();
 44             }
 45             if (exp as MethodCallExpression == null && exp as BinaryExpression == null)
 46                 throw new ArgumentException("不支持表达式的类型", "exp");
 47             if (exp as MethodCallExpression != null)
 48             {
 49                 MethodCallExpression cexp = exp as MethodCallExpression;
 50                 return "";
 51             }
 52             else
 53             {
 54                 switch (exp.NodeType)
 55                 {
 56                     case ExpressionType.Equal:
 57                         return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " = " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
 58                     case ExpressionType.Or:
 59                         return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " or " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
 60                     case ExpressionType.OrElse:
 61                         return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " or " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
 62                     case ExpressionType.AndAlso:
 63                         return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " and " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
 64                     default:
 65                         return "";
 66                 }
 67             }
 68         }
 69         /// <summary>
 70         /// 判断表达式类型
 71         /// </summary>
 72         /// <param name="func">lambda表达式</param>
 73         /// <returns></returns>
 74         private static EnumNodeType CheckExpressionType(Expression func)
 75         {
 76             switch (func.NodeType)
 77             {
 78                 case ExpressionType.AndAlso:
 79                 case ExpressionType.OrElse:
 80                 case ExpressionType.Equal:
 81                 case ExpressionType.GreaterThanOrEqual:
 82                 case ExpressionType.LessThanOrEqual:
 83                 case ExpressionType.GreaterThan:
 84                 case ExpressionType.LessThan:
 85                 case ExpressionType.NotEqual:
 86                     return EnumNodeType.BinaryOperator;
 87                 case ExpressionType.Constant:
 88                     return EnumNodeType.Constant;
 89                 case ExpressionType.MemberAccess:
 90                     return EnumNodeType.MemberAccess;
 91                 case ExpressionType.Call:
 92                     return EnumNodeType.Call;
 93                 case ExpressionType.Not:
 94                 case ExpressionType.Convert:
 95                     return EnumNodeType.UndryOperator;
 96                 default:
 97                     return EnumNodeType.Unknown;
 98             }
 99         }
100         private static string ExpressionTypeToString(ExpressionType type)
101         {
102             switch (type)
103             {
104                 case ExpressionType.Equal:
105                     return " = ";
106                 case ExpressionType.Or:
107                     return " or ";
108                 case ExpressionType.OrElse:
109                     return " or ";
110                 case ExpressionType.AndAlso:
111                     return " and ";
112                 default:
113                     return "";
114             }
115         }
116         /// <summary>
117         /// 判断一元表达式
118         /// </summary>
119         /// <param name="func"></param>
120         /// <returns></returns>
121         private static string VisitUnaryExpression(UnaryExpression func)
122         {
123             var result = ExpressionTypeToString(func.NodeType);
124             var funcType = CheckExpressionType(func.Operand);
125             switch (funcType)
126             {
127                 case EnumNodeType.BinaryOperator:
128                     return result + VisitBinaryExpression(func.Operand as BinaryExpression);
129                 case EnumNodeType.Constant:
130                     return result + VisitConstantExpression(func.Operand as ConstantExpression);
131                 case EnumNodeType.Call:
132                     return result + VisitMethodCallExpression(func.Operand as MethodCallExpression);
133                 case EnumNodeType.UndryOperator:
134                     return result + VisitUnaryExpression(func.Operand as UnaryExpression);
135                 case EnumNodeType.MemberAccess:
136                     return result + VisitMemberAccessExpression(func.Operand as MemberExpression);
137                 default:
138                     throw new NotSupportedException("不支持的操作在一元操作处理中:");
139             }
140         }
141 
142         /// <summary>
143         /// 判断常量表达式
144         /// </summary>
145         /// <param name="func"></param>
146         /// <returns></returns>
147         private static string VisitConstantExpression(ConstantExpression func)
148         {
149             if (func.Value.ToString() == "")
150             {
151                 return "\'\' ";
152             }
153             else if (func.Value.ToString() == "True")
154             {
155                 return "1 = 1 ";
156             }
157             else if (func.Value.ToString() == "False")
158             {
159                 return "0 = 1 ";
160             }
161             else
162             {
163                 return "'" + func.Value.ToString() + "' ";
164 
165             }
166         }
167 
168         /// <summary>
169         /// 判断包含变量的表达式
170         /// </summary>
171         /// <param name="func"></param>
172         /// <returns></returns>
173         private static string VisitMemberAccessExpression(MemberExpression func)
174         {
175             try
176             {
177                 var tablename = func.Expression.Type.Name;
178                 return tablename + "." + func.Member.Name + " ";
179             }
180             catch
181             {
182                 object value;
183                 switch (func.Type.Name)
184                 {
185                     case "Int32":
186                         {
187                             var getter = Expression.Lambda<Func<int>>(func).Compile();
188                             value = getter();
189                         }
190                         break;
191                     case "String":
192                         {
193                             var getter = Expression.Lambda<Func<string>>(func).Compile();
194                             value = "'" + getter() + "'";
195                         }
196                         break;
197                     case "DateTime":
198                         {
199                             var getter = Expression.Lambda<Func<DateTime>>(func).Compile();
200                             value = "'" + getter() + "'";
201                         }
202                         break;
203                     default:
204                         {
205                             var getter = Expression.Lambda<Func<object>>(func).Compile();
206                             value = getter();
207                         }
208                         break;
209                 }
210                 return value.ToString();
211             }
212         }
213         /// <summary>
214         /// 判断包含函数的表达式
215         /// </summary>
216         /// <param name="func"></param>
217         /// <returns></returns>
218         private static String VisitMethodCallExpression(MethodCallExpression func)
219         {
220             if (func.Method.Name.Contains("Contains"))
221             {
222                 if (func.Object.Type.Name.ToLower() == "string")
223                 {
224                     //获得调用者的内容元素
225                     var field = VisitMemberAccessExpression(func.Object as MemberExpression);
226                     //获得字段
227                     var caller = func.Arguments[0];
228                     var param = Expression.Lambda<Func<object>>(caller).Compile();
229                     return field + " like '%" + param() + "%'";
230                 }
231                 else
232                 {
233                     //获得调用者的内容元素
234                     var getter = Expression.Lambda<Func<object>>(func.Object).Compile();
235                     var data = getter() as IEnumerable;
236                     //获得字段
237                     var caller = func.Arguments[0];
238                     while (caller.NodeType == ExpressionType.Call)
239                     {
240                         caller = (caller as MethodCallExpression).Object;
241                     }
242                     var field = VisitMemberAccessExpression(caller as MemberExpression);
243                     var list = (from object i in data select "'" + i + "'").ToList();
244                     return field + " IN (" + string.Join(",", list.Cast<string>().ToArray()) + ") ";
245                 }
246             }
247             else
248             {
249                 throw new NotSupportedException("不支持的函数操作:" + func.Method.Name);
250             }
251         }
252         /// <summary> 
253         /// 判断包含二元运算符的表达式
254         /// </summary>
255         /// <remarks>注意,这个函数使用了递归,修改时注意不要修改了代码顺序和逻辑</remarks>
256         /// <param name="func"></param>
257         private static string VisitBinaryExpression(BinaryExpression func)
258         {
259             var result = "(";
260             var leftType = CheckExpressionType(func.Left);
261             switch (leftType)
262             {
263                 case EnumNodeType.BinaryOperator:
264                     result += VisitBinaryExpression(func.Left as BinaryExpression); break;
265                 case EnumNodeType.Constant:
266                     result += VisitConstantExpression(func.Left as ConstantExpression); break;
267                 case EnumNodeType.MemberAccess:
268                     result += VisitMemberAccessExpression(func.Left as MemberExpression); break;
269                 case EnumNodeType.UndryOperator:
270                     result += VisitUnaryExpression(func.Left as UnaryExpression); break;
271                 case EnumNodeType.Call:
272                     result += VisitMethodCallExpression(func.Left as MethodCallExpression); break;
273                 default:
274                     throw new NotSupportedException("不支持的操作在二元操作处理中:");
275             }
276 
277             result += ExpressionTypeToString(func.NodeType) + " ";
278 
279             var rightType = CheckExpressionType(func.Right);
280             switch (rightType)
281             {
282                 case EnumNodeType.BinaryOperator:
283                     result += VisitBinaryExpression(func.Right as BinaryExpression); break;
284                 case EnumNodeType.Constant:
285                     result += VisitConstantExpression(func.Right as ConstantExpression); break;
286                 case EnumNodeType.MemberAccess:
287                     result += VisitMemberAccessExpression(func.Right as MemberExpression); break;
288                 case EnumNodeType.UndryOperator:
289                     result += VisitUnaryExpression(func.Right as UnaryExpression); break;
290                 case EnumNodeType.Call:
291                     result += VisitMethodCallExpression(func.Right as MethodCallExpression); break;
292                 default:
293                     throw new NotSupportedException("不支持的操作在二元操作处理中:");
294             }
295 
296             result += ") ";
297             return result;
298         }
299     }
300 
301 
302     public enum EnumNodeType
303     {
304         [Description("二元运算符")]
305         BinaryOperator = 1,
306         [Description("一元运算符")]
307         UndryOperator = 2,
308         [Description("常量表达式")]
309         Constant = 3,
310         [Description("成员(变量)")]
311         MemberAccess = 4,
312         [Description("函数")]
313         Call = 5,
314         [Description("未知")]
315         Unknown = -99,
316         [Description("不支持")]
317         NotSupported = -98
318     }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-09-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档