• 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
  • 相关阅读:
    djongo 前端页面展示自定义api返回的列表数据,并拼接到table上
    ou are trying to add a non-nullable field 'address' to person without a default; we can't do that (the database needs something to populate existing rows).
    python string 类型的公钥转换类型并解密
    Django 禁止访问403,CSRF验证失败,相应中断
    springboot async
    此博客可能不再更新,往后博文将发布在 GitHub 中
    css 中 transition 需要注意的问题
    学习笔记(九)
    微信小程序 drawImage 问题
    学习笔记(八)
  • 原文地址:https://www.cnblogs.com/kingkoo/p/2478026.html
Copyright © 2020-2023  润新知