DMSLinq表达式框架实现(三)

IDMSExpressionParser 相关接口

提到这个首先要考虑一下数据库多种类型的情况,也就产生了一个

IDMSDbProvider接口

View Code
 1  /// <summary>
 2     /// DB访问处理接口
 3     /// </summary>
 4     public interface IDMSDbProvider
 5     {
 6         TableConfiguration TableConfig { get; }
 7         /// <summary>
 8         /// 数据访问
 9         /// </summary>
10         IDMSDbAccess DbAccess { get; }
11         /// <summary>
12         /// 参数前缀 SQL为@,ORACLE为:
13         /// </summary>
14         string ParamPrefix { get; }
15         /// <summary>
16         /// 表名,字段名的处理,像表名一般都会加[TableName],[ColumnName] 的左中括号
17         /// </summary>
18         string LeftToken { get; }
19 
20         /// <summary>
21         /// 表名,字段名的处理,像表名一般都会加[TableName],[ColumnName] 的右中括号
22         /// </summary>
23         string RightToken { get; }
24         /// <summary>
25         /// 字段名处理 
26         /// </summary>
27         /// <param name="name"></param>
28         /// <returns></returns>
29         string BuildColumnName(string name);
30         /// <summary>
31         /// 表名处理 
32         /// </summary>
33         /// <param name="name"></param>
34         /// <returns></returns>
35         string BuildTableName(string name);
36         /// <summary>
37         /// 参数处理,返回类型为IDbDataParameter
38         /// </summary>
39         /// <param name="name"></param>
40         /// <param name="value"></param>
41         /// <returns></returns>
42         IDbDataParameter BuildParameter(string name, object value);
43         /// <summary>
44         /// 生成参数名称,这个要根据ParamPrefix来生成,也可以做特殊处理 
45         /// </summary>
46         /// <param name="name"></param>
47         /// <returns></returns>
48         string BuildParameterName(string name);
49     }


我对接口进行了一下合并.其实我认为还有合并的地方.只时一时没有时间整理,先这样吧

View Code
 1  /// <summary>
 2     /// 所有表达式总接口
 3     /// </summary>
 4     public interface IDMSExpressionParser
 5     {
 6         IDMSDbProvider DbProvider { get; set; }
 7         /// <summary>
 8         /// 接口表达式
 9         /// </summary>
10         Expression DMSExpression { get; set; }
11     }
12     /// <summary>
13     /// 表处理表达式
14     /// </summary>
15     public interface IDMSTableExpressionParser : IDMSExpressionParser
16     {
17         Dictionary<string, string> TableNameAlias { get; set; }
18         void Append(IDMSBase dms, Type type);
19         string AnalyzeExpression(ref Dictionary<string, string> KeyValue);
20         string AnalyzeExpression();
21     }
22     /// <summary>
23     /// 列名处理表达式,这个暂未做DISTINCT处理
24     /// </summary>
25     public interface IDMSColumnExpressionParser : IDMSExpressionParser
26     {
27         string AnalyzeExpression(Dictionary<string, string> KeyTable, out string member);
28         string AnalyzeExpression(out IDbDataParameter[] dbParams);
29         string AnalyzeExpression(out string parameters, out IDbDataParameter[] dbParams);
30         void Append<T, T1, T2, TResult>(IDMSBase dms, Expression<Func<T, T1, T2, TResult>> selector);
31         void Append<T, R, TResult>(IDMSBase dms, Expression<Func<T, R, TResult>> selector);
32         void Append<T>(IDMSBase dms, Expression<Func<T, T>> selector);
33         void Append(IDictionary<string, object> fieldNameValuePairs);
34 
35         void AppendResult<T, TReulst>(IDMSBase dms, Expression<Func<T, TReulst>> selector);
36     }
37     /// <summary>
38     /// Where条件处理表达式
39     /// </summary>
40     public interface IDMSWhereExpressionParser : IDMSExpressionParser
41     {
42         string AnalyzeExpression();
43         string AnalyzeExpression(int paramIndex, out IDbDataParameter[] dbParams);
44         string AnalyzeExpression(Dictionary<string, string> keyTable);
45         string AnalyzeExpression(Dictionary<string, string> keyTable, int paramIndex, out IDbDataParameter[] dbParams);
46         void Append<T1, T2>(IDMSBase dms, Expression<Func<T1, T2, bool>> where);
47         void Append<T>(IDMSBase dms, Expression<Func<T, bool>> where);
48         void Append<T>(IDMSBase dms, DMSWhereClip<T> where) where T : IEntity;
49     }
50     /// <summary>
51     /// 排序处理表达式
52     /// </summary>
53     public interface IDMSOrderByExpressionParser : IDMSExpressionParser
54     {
55         void Append(IDMSBase dms, Type type);
56         void Append<T>(IDMSBase dms, Expression<Func<T, T>> selector);
57         string AnalyzeExpression(Dictionary<string, string> KeyTable);
58     }
59     /// <summary>
60     /// 分组处理表达式
61     /// </summary>
62     public interface IDMSGroupByExpressionParser : IDMSExpressionParser
63     {
64         string AnalyzeExpression(Dictionary<string, string> KeyTable);
65         void Append<T, TReulst>(IDMSBase dms, Expression<Func<T, TReulst>> selector);
66         void Append(IDMSBase dms, Type type);
67     }
68     /// <summary>
69     /// HAVING条件处理表达式
70     /// </summary>
71     public interface IDMSHavingExpressionParser : IDMSExpressionParser
72     {
73         void Append(IDMSBase dms, Type type);
74         void Append<T>(IDMSBase dms, Expression<Func<T, bool>> having);
75         string AnalyzeExpression(Dictionary<string, string> KeyTable);
76     }
77     /// <summary>
78     /// 表达式辅助接口
79     /// </summary>
80     public interface IDMSParser
81     {
82 
83     }

接下来就是实现了..我先放个where的实现.其它的后续补上,哈!

IDMSWhereExpressionParser接口实现
  1  public class DMSWhereExpression : DMSExpressionVisitor, IDMSWhereExpressionParser
  2     {
  3         public IDMSDbProvider DbProvider
  4         {
  5             get;
  6             set;
  7         }
  8         private StringBuilder _ResultSql = new StringBuilder();
  9         protected List<IDbDataParameter> _DbParams = new List<IDbDataParameter>();
 10         public Expression DMSExpression { get; set; }
 11         Dictionary<string, string> KeyValue = new Dictionary<string, string>();
 12         private ExpressionType? _LastestOperator = null;
 13         int _ParamIndex = 0;
 14         bool _NeedParams = false;
 15         private bool bConstantStartWith = false;
 16         private bool bConstantEndWith = false;
 17 
 18         private void AnalyzeExpression(bool bNeedParams, Dictionary<string, string> keyTable)
 19         {
 20             this.KeyValue = keyTable;
 21             this._NeedParams = bNeedParams;
 22             this._DbParams = new List<IDbDataParameter>();
 23             this._ResultSql = new StringBuilder();
 24             if (DMSExpression != null)
 25             {
 26                 this.Visit(DMSExpression);
 27             }
 28         }
 29         public string AnalyzeExpression()
 30         {
 31             return AnalyzeExpression(null);
 32         }
 33         public string AnalyzeExpression(Dictionary<string, string> keyTable)
 34         {
 35             this.AnalyzeExpression(false, keyTable);
 36             return this._ResultSql.ToString();
 37         }
 38         public string AnalyzeExpression(Dictionary<string, string> keyTable, int paramIndex, out IDbDataParameter[] dbParams)
 39         {
 40             this._ParamIndex = paramIndex;
 41             this.AnalyzeExpression(true, keyTable);
 42             dbParams = this._DbParams.ToArray();
 43             return this._ResultSql.ToString();
 44         }
 45         public string AnalyzeExpression(int paramIndex, out IDbDataParameter[] dbParams)
 46         {
 47             this._ParamIndex = paramIndex;
 48             this.AnalyzeExpression(true, null);
 49             dbParams = this._DbParams.ToArray();
 50             return this._ResultSql.ToString();
 51         }
 52         public void Append<T>(IDMSBase dms, Expression<Func<T, bool>> where)
 53         {
 54             Expression expression = dms.ModifyExpression(where.Body);
 55             if (expression != null)
 56             {
 57                 if (this.DMSExpression != null)
 58                 {
 59                     this.DMSExpression = Expression.AndAlso(this.DMSExpression, expression);
 60                 }
 61                 else
 62                 {
 63                     this.DMSExpression = expression;
 64                 }
 65             }
 66         }
 67         public void Append<T>(IDMSBase dms, DMSWhereClip<T> where) where T : IEntity
 68         {
 69             Expression expression = dms.ModifyExpression(where.DMSExpression);
 70             if (expression != null)
 71             {
 72                 if (this.DMSExpression != null)
 73                 {
 74                     this.DMSExpression = Expression.AndAlso(this.DMSExpression, expression);
 75                 }
 76                 else
 77                 {
 78                     this.DMSExpression = expression;
 79                 }
 80             }
 81         }
 82         public void Append<T1, T2>(IDMSBase dms, Expression<Func<T1, T2, bool>> where)
 83         {
 84             Expression expression = dms.ModifyExpression(where.Body);
 85             if (expression != null)
 86             {
 87                 if (this.DMSExpression != null)
 88                 {
 89                     this.DMSExpression = Expression.AndAlso(this.DMSExpression, expression);
 90                 }
 91                 else
 92                 {
 93                     this.DMSExpression = expression;
 94                 }
 95             }
 96         }
 97 
 98 
 99 
100         protected override Expression VisitConstant(ConstantExpression c)
101         {
102             StringBuilder stringBuilder = new StringBuilder();
103             if (c.Value != null && c.Type.IsArray)
104             {
105                 Array array = c.Value as Array;
106                 foreach (object current in array)
107                 {
108                     if (current != null)
109                     {
110                         this.AdjustConstant(current, ref stringBuilder);
111                     }
112                     else
113                     {
114                         stringBuilder.Append("NULL");
115                     }
116                     stringBuilder.Append(",");
117                 }
118                 this._ResultSql.Append(stringBuilder.ToString().Trim(new char[] { ',' }));
119             }
120             else
121             {
122                 if (c.Value != null)
123                 {
124                     this.AdjustConstant(c.Value, ref stringBuilder);
125                     this._ResultSql.Append(stringBuilder.ToString());
126                 }
127                 else
128                 {
129                     this._ResultSql.Append("NULL");
130                 }
131             }
132             return base.VisitConstant(c);
133         }
134         protected override Expression VisitMethodCall(MethodCallExpression m)
135         {
136             if (m == null) return m;
137             string methodName = m.Method.Name;
138             MethodInfo method = typeof(DMSWhereExpression).GetMethod("Handle" + methodName);
139             if (method != null)
140             {
141                 if (methodName.ToUpper() == "LIKE")
142                 {
143                     this.bConstantStartWith = this.bConstantEndWith = true;
144                 }
145                 else if (methodName.ToUpper() == "STARTWITH")
146                 {
147                     this.bConstantStartWith = true;
148                 }
149                 else if (methodName.ToUpper() == "ENDWITH")
150                 {
151                     this.bConstantStartWith = true;
152                 }
153                 Expression exp = method.Invoke(this, new object[] { m }) as Expression;
154                 this.bConstantStartWith = this.bConstantEndWith = false;
155                 return exp;
156             }
157             return base.VisitMethodCall(m);
158         }
159         protected override Expression VisitNewArray(NewArrayExpression na)
160         {
161             foreach (Expression current in na.Expressions)
162             {
163                 this.Visit(current);
164                 this._ResultSql.Append(" ");
165             }
166             return na;
167         }
168         protected override Expression VisitUnary(UnaryExpression u)
169         {
170             return base.VisitUnary(u);
171         }
172         protected override Expression VisitBinary(BinaryExpression b)
173         {
174             this._ResultSql.Append("(");
175             this.Visit(b.Left);
176             this._LastestOperator = new ExpressionType?(b.NodeType);
177             this._ResultSql.Append(" " + DMSOperators.FormatBinaryOperator(this._LastestOperator) + " ");
178             this.Visit(b.Right);
179             this._ResultSql.Append(")");
180             return b;
181         }
182         protected override Expression VisitMemberAccess(MemberExpression m)
183         {
184             if (m.Expression is ParameterExpression)
185             {
186                 string text = string.Empty;
187                 Type valueType = m.Member.ReflectedType;
188                 if (valueType != null && this.KeyValue != null && this.KeyValue.ContainsKey(valueType.ToString()))
189                 {
190                     text = this.KeyValue[valueType.ToString()];
191                     if (this.DbProvider != null)
192                     {
193                         text = this.DbProvider.BuildColumnName(text);
194                     }
195                     this._ResultSql.Append(text + ".");
196                 }
197                 text = m.Member.Name;
198                 if (this.DbProvider != null)
199                 {
200                     text = this.DbProvider.BuildColumnName(text);
201                 }
202                 this._ResultSql.Append(text);
203                 return m;
204             }
205             return base.VisitMemberAccess(m);
206         }
207         protected virtual void AdjustConstant(object value, ref StringBuilder sb)
208         {
209             
210             Type type = value.GetType();
211             if (type == typeof(string) || type == typeof(bool) || type == typeof(DateTime) || type == typeof(Guid))
212             {
213                 if (bConstantStartWith)
214                 {
215                     value = value + "%";
216                 }
217                 if (bConstantEndWith)
218                 {
219                     value = "%" + value;
220                 }   
221                 if (this._NeedParams && this.DbProvider != null)
222                 {
223                     this._ParamIndex++;
224                     string text = this.DbProvider.BuildParameterName("p" + this._ParamIndex.ToString());
225                     IDbDataParameter item = this.DbProvider.BuildParameter(text, value);
226                     this._DbParams.Add(item);
227                     sb.Append(text);
228                     return;
229                 }
230                 if (type != typeof(bool))
231                 {
232                     sb.Append("'");
233                     value = value.ToString().Replace("'", "''");
234                 }
235                 else
236                 {
237                     value = ((bool)value) ? "1" : "0";
238                 }
239 
240 
241                 
242                 sb.Append(value);
243                 if (type != typeof(bool))
244                 {
245                     sb.Append("'");
246                     return;
247                 }
248             }
249             else
250             {
251                 if (bConstantStartWith)
252                 {
253                     value = value + "%";
254                 }
255                 if (bConstantEndWith)
256                 {
257                     value = "%" + value;
258                 }
259                 sb.Append(value);
260             }
261         }
262 
263 
264         public virtual Expression HandleIn(MethodCallExpression m)
265         {
266             this._ResultSql.Append("(");
267             this.Visit(m.Arguments[0]);
268             this._ResultSql.Append(" IN (");
269             if (m.Arguments[1].Type.BaseType == typeof(DMS))
270             {
271                 UnaryExpression castMethodCall = Expression.Convert(m.Arguments[1], typeof(DMS));
272                 LambdaExpression exp = Expression.Lambda(castMethodCall);
273                 var dynamicObject = exp.Compile();
274                 var obj = dynamicObject.DynamicInvoke() as DMS;
275                 this._ResultSql.Append(obj.GetResultSql().Trim());
276             }
277             else
278                 this.Visit(m.Arguments[1]);
279             this._ResultSql.Append("))");
280             return m;
281         }
282         public virtual Expression HandleNotIn(MethodCallExpression m)
283         {
284             this._ResultSql.Append("(");
285             this.Visit(m.Arguments[0]);
286             this._ResultSql.Append(" NOT IN (");
287             if (m.Arguments[1].Type.BaseType == typeof(DMS))
288             {
289                 UnaryExpression castMethodCall = Expression.Convert(m.Arguments[1], typeof(DMS));
290                 LambdaExpression exp = Expression.Lambda(castMethodCall);
291                 var dynamicObject = exp.Compile();
292                 var obj = dynamicObject.DynamicInvoke() as DMS;
293                 this._ResultSql.Append(obj.GetResultSql().Trim());
294             }
295             else
296                 this.Visit(m.Arguments[1]);
297             this._ResultSql.Append("))");
298             return m;
299         }
300         public virtual Expression HandleLike(MethodCallExpression m)
301         {
302             this._ResultSql.Append("(");
303             this.Visit(m.Arguments[0]);
304             this._ResultSql.Append(" Like ");
305             this.Visit(m.Arguments[1]);
306             this._ResultSql.Append(")");
307             return m;
308         }
309         public virtual Expression HandleStartWith(MethodCallExpression m)
310         {
311             this._ResultSql.Append("(");
312             this.Visit(m.Arguments[0]);
313             this._ResultSql.Append(" Like ");
314             this.Visit(m.Arguments[1]);
315             this._ResultSql.Append(")");
316             return m;
317         }
318         public virtual Expression HandleEndWith(MethodCallExpression m)
319         {
320             this._ResultSql.Append("(");
321             this.Visit(m.Arguments[0]);
322             this._ResultSql.Append(" Like ");
323             this.Visit(m.Arguments[1]);
324             this._ResultSql.Append(")");
325             return m;
326         }
327 
328         public virtual Expression HandleIsNull(MethodCallExpression m)
329         {
330             this._ResultSql.Append("(");
331             this.Visit(m.Arguments[0]);
332             this._ResultSql.Append(" IS NULL)");
333             return m;
334         }
335 
336         public virtual Expression HandleIsNotNull(MethodCallExpression m)
337         {
338             this._ResultSql.Append("(");
339             this.Visit(m.Arguments[0]);
340             this._ResultSql.Append(" IS NOT NULL)");
341             return m;
342         }
343 
344         public virtual Expression HandleCountAll(MethodCallExpression m)
345         {
346             this._ResultSql.Append(" Count(*) ");
347             return m;
348         }
349         public virtual Expression HandleCount(MethodCallExpression m)
350         {
351             this.MethodFunc(m.Method.Name, m);
352             return m;
353         }
354         public virtual Expression HandleLen(MethodCallExpression m)
355         {
356             this.MethodFunc(m.Method.Name, m);
357             return m;
358         }
359         public virtual Expression HandleMax(MethodCallExpression m)
360         {
361             this.MethodFunc(m.Method.Name, m);
362             return m;
363         }
364         public virtual Expression HandleMin(MethodCallExpression m)
365         {
366             this.MethodFunc(m.Method.Name, m);
367             return m;
368         }
369         public virtual Expression HandleAvg(MethodCallExpression m)
370         {
371             this.MethodFunc(m.Method.Name, m);
372             return m;
373         }
374         public virtual Expression HandleSum(MethodCallExpression m)
375         {
376             this.MethodFunc(m.Method.Name, m);
377             return m;
378         }
379 
380         public virtual Expression HandleAs(MethodCallExpression m)
381         {
382             this.Visit(m.Arguments[0]);
383             object value = LocalDMSExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
384             if (value != null)
385             {
386                 this._ResultSql.Append(" AS ");
387                 this._ResultSql.Append(this.DbProvider.LeftToken + value + this.DbProvider.RightToken);
388             }
389             return m;
390         }
391         public virtual Expression HandleSpecialColumn(MethodCallExpression m)
392         {
393             object value = LocalDMSExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
394             if (value != null)
395             {
396                 string text = value.ToString();
397                 if (this.DbProvider != null)
398                 {
399                     text = this.DbProvider.BuildColumnName(text);
400                 }
401                 this._ResultSql.Append(text);
402             }
403             return m;
404         }
405         public virtual Expression HandleNewID(MethodCallExpression m)
406         {
407             return m;
408         }
409         protected void MethodFunc(string methodName, MethodCallExpression m)
410         {
411             this._ResultSql.Append(" " + methodName + "(");
412             this.Visit(m.Arguments[0]);
413             this._ResultSql.Append(") ");
414         }
415         public virtual Expression HandleGreaterThan(MethodCallExpression m)
416         {
417             this.CompareFunc(">", m);
418             return m;
419         }
420         public virtual Expression HandleGreaterThanOrEqual(MethodCallExpression m)
421         {
422             this.CompareFunc(">=", m);
423             return m;
424         }
425         public virtual Expression HandleLessThan(MethodCallExpression m)
426         {
427             this.CompareFunc("<", m);
428             return m;
429         }
430         public virtual Expression HandleLessThanOrEqual(MethodCallExpression m)
431         {
432             this.CompareFunc("<=", m);
433             return m;
434         }
435         protected void CompareFunc(string CompareStr, MethodCallExpression m)
436         {
437             this._ResultSql.Append("(");
438             this.Visit(m.Arguments[0]);
439             this._ResultSql.Append(" " + CompareStr + " ");
440             this.Visit(m.Arguments[1]);
441             this._ResultSql.Append(")");
442         }
443 
444 
445 
446 
447     }

  相关项目下载可以联系本人QQ;

千人.NET交流群:18362376,因为有你,代码变得更简单,加群请输入cnblogs
原文地址:https://www.cnblogs.com/kingkoo/p/2478026.html