• DMSLinq表达式框架实现(四)


    这里就不写废话了.直接上代码,代码中也有注释

      1 /// <summary>
      2     /// 列表达式处理器
      3     /// </summary>
      4     public class DMSColumnExpression : DMSExpressionVisitor, IDMSColumnExpressionParser
      5     {
      6         /// <summary>
      7         /// DB访问处理接口
      8         /// </summary>
      9         public IDMSDbProvider DbProvider { get; set; }
     10         /// <summary>
     11         /// 接口表达式
     12         /// </summary>
     13         public Expression DMSExpression { get; set; }
     14         /// <summary>
     15         /// 是否DISTINCT列
     16         /// </summary>
     17         public bool IsDistinct { get; set; }
     18         /// <summary>
     19         /// 是否TOP 1列
     20         /// </summary>
     21         public bool IsFirst { get; set; }
     22         /// <summary>
     23         /// 是否使用参数
     24         /// </summary>
     25         private bool bNeedParams { get; set; }
     26         /// <summary>
     27         /// 
     28         /// </summary>
     29         StringBuilder _ResultSql = new StringBuilder();
     30         /// <summary>
     31         /// 
     32         /// </summary>
     33         StringBuilder _MemberSql = new StringBuilder();
     34         private IDMSBase dmsBase { get; set; }
     35         Dictionary<string, string> KeyValue = new Dictionary<string, string>();
     36         /// <summary>
     37         /// 
     38         /// </summary>
     39         private System.Reflection.MemberInfo memberInfo;
     40         private IDictionary<string, object> FieldNameValuePairs
     41         {
     42             get;
     43             set;
     44         }
     45         /// <summary>
     46         /// 生成列查询SQL语句,并返回字段不带前缀的member
     47         /// </summary>
     48         /// <param name="KeyTable"></param>
     49         /// <param name="member"></param>
     50         /// <returns></returns>
     51         public string AnalyzeExpression(Dictionary<string, string> KeyTable, out string member)
     52         {
     53             this.KeyValue = KeyTable;
     54             this.memberInfo = null;
     55             this._ResultSql = new StringBuilder();
     56             this._MemberSql = new StringBuilder();
     57             if (DMSExpression != null)
     58             {
     59                 this.Visit(DMSExpression);
     60             }
     61             member = _MemberSql.ToString();
     62             return this._ResultSql.ToString();
     63         }
     64         /// <summary>
     65         /// UPDATE
     66         /// </summary>
     67         /// <param name="dbParams"></param>
     68         /// <returns></returns>
     69         public string AnalyzeExpression(out IDbDataParameter[] dbParams)
     70         {
     71             this._ResultSql = new StringBuilder();
     72             int num = 0;
     73             foreach (KeyValuePair<string, object> current in FieldNameValuePairs)
     74             {
     75                 if (current.Value != null)
     76                 {
     77                     num++;
     78                 }
     79             }
     80             IDbDataParameter[] array = new IDbDataParameter[0];
     81             if (bNeedParams)
     82             {
     83                 array = new IDbDataParameter[num];
     84             }
     85             string[] includeColumns = new string[num];
     86             string[] includeColumnValues = new string[num];
     87             num = 0;
     88             Type currentType = null;
     89             if (dmsBase != null)
     90             {
     91                 currentType = Type.GetType(dmsBase.CurrentType);
     92             }
     93             foreach (KeyValuePair<string, object> current in FieldNameValuePairs)
     94             {
     95                 includeColumns[num] = this.DbProvider.BuildColumnName(current.Key);
     96                 if (bNeedParams)
     97                 {
     98                     includeColumnValues[num] = this.DbProvider.BuildParameterName(current.Key);
     99                     array[num] = this.DbProvider.BuildParameter(current.Key, current.Value);
    100                 }
    101                 else
    102                 {
    103                     AdjustConstant(num, ref includeColumnValues, current, currentType);
    104                 }
    105                 num++;
    106             }
    107 
    108             for (int ndx = 0; ndx < includeColumns.Length; ndx++)
    109             {
    110                 _ResultSql.AppendFormat("{0}={1},", includeColumns[ndx], includeColumnValues[ndx]);
    111             }
    112             dbParams = array;
    113             return this._ResultSql.ToString().TrimEnd(new char[] { ',' });
    114         }
    115         /// <summary>
    116         /// INSERT
    117         /// </summary>
    118         /// <param name="parameters"></param>
    119         /// <param name="dbParams"></param>
    120         /// <returns></returns>
    121         public string AnalyzeExpression(out string parameters, out IDbDataParameter[] dbParams)
    122         {
    123             this._ResultSql = new StringBuilder();
    124             StringBuilder strParams = new StringBuilder();
    125             int num = 0;
    126             foreach (KeyValuePair<string, object> current in FieldNameValuePairs)
    127             {
    128                 if (current.Value != null)
    129                 {
    130                     num++;
    131                 }
    132             }
    133             IDbDataParameter[] array = new IDbDataParameter[0];
    134             if (bNeedParams)
    135             {
    136                 array = new IDbDataParameter[num];
    137             }
    138             string[] includeColumns = new string[num];
    139             string[] includeColumnValues = new string[num];
    140             num = 0;
    141             Type currentType = null;
    142             if (dmsBase != null)
    143             {
    144                 currentType = Type.GetType(dmsBase.CurrentType);
    145             }
    146             foreach (KeyValuePair<string, object> current in FieldNameValuePairs)
    147             {
    148                 includeColumns[num] = this.DbProvider.BuildColumnName(current.Key);
    149                 if (bNeedParams)
    150                 {
    151                     includeColumnValues[num] = this.DbProvider.BuildParameterName(current.Key);
    152                     array[num] = this.DbProvider.BuildParameter(current.Key, current.Value);
    153                 }
    154                 else
    155                 {
    156 
    157                     AdjustConstant(num, ref includeColumnValues, current, currentType);
    158                 }
    159                 num++;
    160             }
    161 
    162             for (int ndx = 0; ndx < includeColumns.Length; ndx++)
    163             {
    164                 _ResultSql.AppendFormat("{0},", includeColumns[ndx]);
    165                 strParams.AppendFormat("{0},", includeColumnValues[ndx]);
    166             }
    167             dbParams = array;
    168             parameters = strParams.ToString().TrimEnd(new char[] { ',' });
    169             return this._ResultSql.ToString().TrimEnd(new char[] { ',' });
    170         }
    171         /// <summary>
    172         ///过滤参数值
    173         /// </summary>
    174         /// <param name="num"></param>
    175         /// <param name="includeColumnValues"></param>
    176         /// <param name="current"></param>
    177         /// <param name="currentType"></param>
    178         private void AdjustConstant(int num, ref string[] includeColumnValues, KeyValuePair<string, object> current, Type currentType)
    179         {
    180             bool IsStringType = false;
    181             object value = current.Value;
    182             if (currentType != null)
    183             {
    184                 PropertyInfo propertyInfo = currentType.GetProperty(current.Key);
    185                 if (propertyInfo != null)
    186                 {
    187                     if (!propertyInfo.PropertyType.IsStringType())
    188                     {
    189                         IsStringType = true;
    190                         if (propertyInfo.PropertyType.IsBooleanType())
    191                         {
    192                             if (value != null)
    193                             {
    194                                 value = (bool)value ? "1" : "0";
    195                             }
    196                         }
    197                     }
    198                 }
    199             }
    200             if (!IsStringType && value != null)
    201             {
    202                 value = "'" + value.ToString().Replace("'", "''") + "'";
    203             }
    204             includeColumnValues[num] = value == null ? "NULL" : value.ToString();
    205         }
    206 
    207         #region Append
    208         /// <summary>
    209         /// 添加DMS
    210         /// </summary>
    211         /// <typeparam name="T"></typeparam>
    212         /// <param name="dms"></param>
    213         /// <param name="Body"></param>
    214         public void Append<T>(IDMSBase dms, Expression Body)
    215         {
    216             this.dmsBase = dms;
    217             if (Body is NewExpression)
    218             {
    219                 NewExpression newExpression = Body as NewExpression;
    220                 if (newExpression != null)
    221                 {
    222                     Expression exp = dms.ModifyExpression(newExpression);
    223                     DMSExpression = exp;
    224                 }
    225             }
    226             else if (Body is MethodCallExpression)
    227             {
    228                 MethodCallExpression methodCallExpression = Body as MethodCallExpression;
    229                 if (methodCallExpression != null)
    230                 {
    231                     NewArrayExpression newArrayExpression = (methodCallExpression.Arguments[1] as NewArrayExpression);
    232                     DMSExpression = newArrayExpression;
    233                 }
    234             }
    235             else if (Body is NewArrayExpression)
    236             {
    237                 NewArrayExpression newArrayExpression = Body as NewArrayExpression;
    238                 DMSExpression = newArrayExpression;
    239             }
    240         }
    241         /// <summary>
    242         /// 单表添加一个列名
    243         /// </summary>
    244         /// <typeparam name="T"></typeparam>
    245         /// <param name="dms"></param>
    246         /// <param name="selector"></param>
    247         public void Append<T>(IDMSBase dms, Expression<Func<T, T>> selector)
    248         {
    249             this.dmsBase = dms;
    250             if (selector != null)
    251             {
    252                 Expression body = selector.Body;
    253                 this.Append<T>(dms, body);
    254             }
    255         }
    256         /// <summary>
    257         /// 两表连接添加一个NEW实例
    258         /// </summary>
    259         /// <typeparam name="T"></typeparam>
    260         /// <typeparam name="R"></typeparam>
    261         /// <typeparam name="TResult"></typeparam>
    262         /// <param name="dms"></param>
    263         /// <param name="selector"></param>
    264         public void Append<T, R, TResult>(IDMSBase dms, Expression<Func<T, R, TResult>> selector)
    265         {
    266             this.dmsBase = dms;
    267             if (selector != null)
    268             {
    269                 NewExpression newExpression = selector.Body as NewExpression;
    270                 if (newExpression != null)
    271                 {
    272                     DMSExpression = dms.ModifyExpression(newExpression);
    273                 }
    274             }
    275             else
    276             {
    277                 NewExpression newExpression = Expression.New(typeof(TResult));
    278                 if (newExpression != null)
    279                 {
    280                     DMSExpression = dms.ModifyExpression(newExpression);
    281                 }
    282             }
    283         }
    284         /// <summary>
    285         /// 三表连接添加一个NEW实例
    286         /// </summary>
    287         /// <typeparam name="T"></typeparam>
    288         /// <typeparam name="T1"></typeparam>
    289         /// <typeparam name="T2"></typeparam>
    290         /// <typeparam name="TResult"></typeparam>
    291         /// <param name="dms"></param>
    292         /// <param name="selector"></param>
    293         public void Append<T, T1, T2, TResult>(IDMSBase dms, Expression<Func<T, T1, T2, TResult>> selector)
    294         {
    295             this.dmsBase = dms;
    296             if (selector != null)
    297             {
    298                 NewExpression newExpression = selector.Body as NewExpression;
    299                 if (newExpression != null)
    300                 {
    301                     DMSExpression = dms.ModifyExpression(newExpression);
    302                 }
    303             }
    304         }
    305         /// <summary>
    306         /// 添加一个NEW实例到列查询中
    307         /// </summary>
    308         /// <typeparam name="T"></typeparam>
    309         /// <typeparam name="TReulst"></typeparam>
    310         /// <param name="dms"></param>
    311         /// <param name="selector"></param>
    312         public void AppendResult<T, TReulst>(IDMSBase dms, Expression<Func<T, TReulst>> selector)
    313         {
    314             this.dmsBase = dms;
    315             if (selector != null)
    316             {
    317                 if (selector.Body is NewExpression)
    318                 {
    319                     NewExpression newExpression = selector.Body as NewExpression;
    320                     if (newExpression != null)
    321                     {
    322                         DMSExpression = dms.ModifyExpression(newExpression);
    323                     }
    324                 }
    325                 else if (selector.Body is MethodCallExpression)
    326                 {
    327                     MethodCallExpression methodCallExpression = selector.Body as MethodCallExpression;
    328                     if (methodCallExpression != null)
    329                     {
    330                         NewArrayExpression newArrayExpression = (methodCallExpression.Arguments[1] as NewArrayExpression);
    331                         DMSExpression = newArrayExpression;
    332                     }
    333                 }
    334             }
    335         }
    336         /// <summary>
    337         /// UPDATE,DELETE,INSERT字段添加组合,
    338         /// </summary>
    339         /// <param name="dms"></param>
    340         /// <param name="bNeedParams">是否使用参数形式</param>
    341         /// <param name="fieldNameValuePairs">改变字段(MAPPNG)集合</param>
    342         public void Append(IDMSBase dms, bool bNeedParams, IDictionary<string, object> fieldNameValuePairs)
    343         {
    344             this.dmsBase = dms;
    345             this.bNeedParams = bNeedParams;
    346             this.FieldNameValuePairs = fieldNameValuePairs;
    347         }
    348         #endregion
    349 
    350         /// <summary>
    351         /// 重载访问NewExpression
    352         /// </summary>
    353         /// <param name="nex"></param>
    354         /// <returns></returns>
    355         protected override NewExpression VisitNew(NewExpression nex)
    356         {
    357             int ndx = 0;
    358             foreach (Expression exp in nex.Arguments)
    359             {
    360                 memberInfo = null;
    361                 if (nex.Members.Count > ndx)
    362                 {
    363                     memberInfo = nex.Members[ndx];
    364                 }
    365                 this.Visit(exp);
    366                 ndx++;
    367                 if (!this._ResultSql.ToString().EndsWith(","))
    368                 {
    369                     this._ResultSql.Append(",");
    370                 }
    371                 if (!this._MemberSql.ToString().EndsWith(","))
    372                 {
    373                     this._MemberSql.Append(",");
    374                 }
    375             }
    376             if (this._ResultSql.ToString().EndsWith(","))
    377             {
    378                 this._ResultSql.Remove(this._ResultSql.Length - 1, 1);
    379             }
    380             this._ResultSql.Append(" ");
    381             if (this._MemberSql.ToString().EndsWith(","))
    382             {
    383                 this._MemberSql.Remove(this._MemberSql.Length - 1, 1);
    384             }
    385             this._MemberSql.Append(" ");
    386             return nex;
    387         }
    388         /// <summary>
    389         /// 重载访问NewArrayExpression
    390         /// </summary>
    391         /// <param name="na"></param>
    392         /// <returns></returns>
    393         protected override Expression VisitNewArray(NewArrayExpression na)
    394         {
    395             foreach (Expression current in na.Expressions)
    396             {
    397                 this.Visit(current);
    398                 this._ResultSql.Append(",");
    399             }
    400             if (this._ResultSql.ToString().EndsWith(","))
    401             {
    402                 this._ResultSql.Remove(this._ResultSql.Length - 1, 1);
    403             }
    404             return na;
    405         }
    406         /// <summary>
    407         /// 重载访问MemberExpression
    408         /// </summary>
    409         /// <param name="m"></param>
    410         /// <returns></returns>
    411         protected override Expression VisitMemberAccess(MemberExpression m)
    412         {
    413             if (m.Expression is ParameterExpression)
    414             {
    415                 string text = string.Empty;
    416                 Type valueType = m.Member.ReflectedType;
    417                 if (valueType != null && this.KeyValue.ContainsKey(valueType.ToString()))
    418                 {
    419                     text = this.KeyValue[valueType.ToString()];
    420                     if (this.DbProvider != null)
    421                     {
    422                         text = this.DbProvider.BuildColumnName(text);
    423                     }
    424                     this._ResultSql.Append(text + ".");
    425                 }
    426 
    427                 text = m.Member.Name;
    428                 if (text.StartsWith("get_", StringComparison.CurrentCultureIgnoreCase))
    429                 {
    430                     text = text.Substring(4);
    431                 }
    432                 if (this.DbProvider != null)
    433                 {
    434                     text = this.DbProvider.BuildColumnName(text);
    435                 }
    436                 this._ResultSql.Append(text);
    437 
    438                 if (this.memberInfo != null)
    439                 {
    440                     string memberName = (memberInfo.Name);
    441                     if (memberName.StartsWith("get_", StringComparison.CurrentCultureIgnoreCase))
    442                     {
    443                         memberName = memberName.Substring(4);
    444                     }
    445                     if (this.DbProvider != null)
    446                     {
    447                         memberName = this.DbProvider.BuildColumnName(memberName);
    448                     }
    449                     if (text != memberName)
    450                     {
    451                         this._ResultSql.Append(" AS " + memberName);
    452                     }
    453                     this._MemberSql.Append(memberName);
    454                 }
    455                 return m;
    456             }
    457             return base.VisitMemberAccess(m);
    458         }
    459         /// <summary>
    460         /// 重载访问ConstantExpression
    461         /// </summary>
    462         /// <param name="c"></param>
    463         /// <returns></returns>
    464         protected override Expression VisitConstant(ConstantExpression c)
    465         {
    466             if (c.Value != null)
    467             {
    468                 this._ResultSql.Append(c.Value.ToString());
    469                 this._ResultSql.Append(" ");
    470             }
    471             return base.VisitConstant(c);
    472         }
    473         /// <summary>
    474         /// 重载访问MethodCallExpression
    475         /// </summary>
    476         /// <param name="m"></param>
    477         /// <returns></returns>
    478         protected override Expression VisitMethodCall(MethodCallExpression m)
    479         {
    480             if (m == null) return m;
    481             string methodName = m.Method.Name;
    482             MethodInfo method = typeof(DMSColumnExpression).GetMethod("Handle" + methodName);
    483             if (method != null)
    484             {
    485                 Expression exp = method.Invoke(this, new object[] { m }) as Expression;
    486                 return exp;
    487             }
    488             return base.VisitMethodCall(m);
    489         }
    490 
    491         /// <summary>
    492         /// 处理COUNT(*)
    493         /// </summary>
    494         /// <param name="m"></param>
    495         /// <returns></returns>
    496         public virtual Expression HandleCountAll(MethodCallExpression m)
    497         {
    498             this._ResultSql.Append(" Count(*) ");
    499             return m;
    500         }
    501         /// <summary>
    502         /// 处理COUNT(列)
    503         /// </summary>
    504         /// <param name="m"></param>
    505         /// <returns></returns>
    506         public virtual Expression HandleCount(MethodCallExpression m)
    507         {
    508             this.MethodFunc(m.Method.Name, m);
    509             return m;
    510         }
    511         /// <summary>
    512         /// 处理LEN(列)
    513         /// </summary>
    514         /// <param name="m"></param>
    515         /// <returns></returns>
    516         public virtual Expression HandleLen(MethodCallExpression m)
    517         {
    518             this.MethodFunc(m.Method.Name, m);
    519             return m;
    520         }
    521         /// <summary>
    522         /// 处理MAX(列)
    523         /// </summary>
    524         /// <param name="m"></param>
    525         /// <returns></returns>
    526         public virtual Expression HandleMax(MethodCallExpression m)
    527         {
    528             this.MethodFunc(m.Method.Name, m);
    529             return m;
    530         }
    531         /// <summary>
    532         /// 处理MIN(列)
    533         /// </summary>
    534         /// <param name="m"></param>
    535         /// <returns></returns>
    536         public virtual Expression HandleMin(MethodCallExpression m)
    537         {
    538             this.MethodFunc(m.Method.Name, m);
    539             return m;
    540         }
    541         /// <summary>
    542         /// 处理AVG(列)
    543         /// </summary>
    544         /// <param name="m"></param>
    545         /// <returns></returns>
    546         public virtual Expression HandleAvg(MethodCallExpression m)
    547         {
    548             this.MethodFunc(m.Method.Name, m);
    549             return m;
    550         }
    551         /// <summary>
    552         /// 处理SUM(列)
    553         /// </summary>
    554         /// <param name="m"></param>
    555         /// <returns></returns>
    556         public virtual Expression HandleSum(MethodCallExpression m)
    557         {
    558             this.MethodFunc(m.Method.Name, m);
    559             return m;
    560         }
    561         /// <summary>
    562         /// 处理 (列) AS 别名
    563         /// </summary>
    564         /// <param name="m"></param>
    565         /// <returns></returns>
    566         public virtual Expression HandleAs(MethodCallExpression m)
    567         {
    568             this.Visit(m.Arguments[0]);
    569             object value = LocalDMSExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
    570             if (value != null)
    571             {
    572                 this._ResultSql.Append(" AS ");
    573                 this._ResultSql.Append(this.DbProvider.LeftToken + value + this.DbProvider.RightToken);
    574             }
    575             return m;
    576         }
    577         /// <summary>
    578         /// 
    579         /// </summary>
    580         /// <param name="m"></param>
    581         /// <returns></returns>
    582         public virtual Expression HandleSpecialColumn(MethodCallExpression m)
    583         {
    584             object value = LocalDMSExpressionChecker.ConvertConstantExpression(m.Arguments[1]).Value;
    585             if (value != null)
    586             {
    587                 string text = value.ToString();
    588                 if (this.DbProvider != null)
    589                 {
    590                     text = this.DbProvider.BuildColumnName(text);
    591                 }
    592                 this._ResultSql.Append(text);
    593             }
    594             return m;
    595         }
    596         /// <summary>
    597         /// 处理方法拼接SQL
    598         /// </summary>
    599         /// <param name="methodName"></param>
    600         /// <param name="m"></param>
    601         protected void MethodFunc(string methodName, MethodCallExpression m)
    602         {
    603             this._ResultSql.Append(" " + methodName + "(");
    604             this.Visit(m.Arguments[0]);
    605             this._ResultSql.Append(") ");
    606         }
    607     }

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

    千人.NET交流群:18362376,因为有你,代码变得更简单,加群请输入cnblogs
  • 相关阅读:
    前端项目升级和降级依赖的最佳姿势
    如果你github提交代码,报错remote: Support for password authentication was removed on August 13, 2021.
    js将连接符命名和驼峰命名互转
    滚动条常用样式
    计算该浏览器中滚动条的默认宽度
    解决webpack-dev-server启动后localhost:port可以访问,IP:port不能访问的问题
    获取滚动条宽度的方法
    mysql中的数据类型
    数据库和表的操作
    mysql插入,删除,修改记录
  • 原文地址:https://www.cnblogs.com/kingkoo/p/2496702.html
Copyright © 2020-2023  润新知