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