zoukankan      html  css  js  c++  java
  • EF架构~过滤导航属性等,拼接SQL字符串

    拼接T—SQL串,并使它具有通用性

    好处:与服务器建立一次连接,给服务器发一条SQL命令,即可实现

    代码如下:

    复制代码
     1   /// <summary>
     2         /// 构建Insert语句串
     3         /// 主键为自增时,如果主键值为0,我们将主键插入到SQL串中
     4         /// </summary>
     5         /// <typeparam name="TEntity"></typeparam>
     6         /// <param name="entity"></param>
     7         /// <returns></returns>
     8         private Tuple<string, object[]> CreateInsertSQL<TEntity>(TEntity entity) where TEntity : class
     9         {
    10             if (entity == null)
    11                 throw new ArgumentException("The database entity can not be null.");
    12 
    13             Type entityType = entity.GetType();
    14             var table = entityType.GetProperties().Where(i => i.PropertyType != typeof(EntityKey)
    15                && i.PropertyType != typeof(EntityState)
    16                && i.GetValue(entity, null) != null
    17                && (i.PropertyType.IsValueType || i.PropertyType == typeof(string)))
    18                .ToArray();//过滤主键,航行属性,状态属性等
    19             List<string> pkList = GetPrimaryKey<TEntity>().Select(i => i.Name).ToList();
    20 
    21             List<object> arguments = new List<object>();
    22             StringBuilder fieldbuilder = new StringBuilder();
    23             StringBuilder valuebuilder = new StringBuilder();
    24 
    25             fieldbuilder.Append(" INSERT INTO " + string.Format("[{0}]", entityType.Name) + " (");
    26 
    27             foreach (var member in table)
    28             {
    29                 if (pkList.Contains(member.Name) && Convert.ToString(member.GetValue(entity, null)) == "0")
    30                     continue;
    31                 object value = member.GetValue(entity, null);
    32                 if (value != null)
    33                 {
    34                     if (arguments.Count != 0)
    35                     {
    36                         fieldbuilder.Append(", ");
    37                         valuebuilder.Append(", ");
    38                     }
    39 
    40                     fieldbuilder.Append(member.Name);
    41                     if (member.PropertyType == typeof(string) || member.PropertyType == typeof(DateTime))
    42                         valuebuilder.Append("'{" + arguments.Count + "}'");
    43                     else
    44                         valuebuilder.Append("{" + arguments.Count + "}");
    45                     if (value.GetType() == typeof(string))
    46                         value = value.ToString().Replace("'", "char(39)");
    47                     arguments.Add(value);
    48 
    49                 }
    50             }
    51 
    52 
    53             fieldbuilder.Append(") Values (");
    54 
    55             fieldbuilder.Append(valuebuilder.ToString());
    56             fieldbuilder.Append(");");
    57             return new Tuple<string, object[]>(fieldbuilder.ToString(), arguments.ToArray());
    58         }
    复制代码

    对于EF架构中的批量更新操作,需要我们为实体的导航属性进行手动的标示,因为EF生成的实体中没有一个特殊的说明,所以,我们必须要告诉系统,哪个属性是导航属性,而导航属性是我们不去进行update的。

    复制代码
    1    /// <summary>
    2     /// 属性的导航属性
    3     /// </summary>
    4     public class NavigationAttribute : Attribute
    5     {
    6 
    7     }
    复制代码

    而对于要进行批量更新的实体,我们需要为导航属性添加这个特性

    复制代码
    1    public class User
    2     {
    3         public int UserID { get; set; }
    4         [Navigation]
    5         public User_Extension User_Extension { get; set; }
    6     }
    复制代码

    而对于我们构建批量Update语句,请看代码,它需要对导航属性进行过滤

    复制代码
     1         /// <summary>
     2         /// 构建Update语句串
     3         /// </summary>
     4         /// <typeparam name="TEntity"></typeparam>
     5         /// <param name="entity"></param>
     6         /// <returns></returns>
     7         private Tuple<string, object[]> CreateUpdateSQL<TEntity>(TEntity entity) where TEntity : class
     8         {
     9             if (entity == null)
    10                 throw new ArgumentException("The database entity can not be null.");
    11             List<string> pkList = GetPrimaryKey<TEntity>().Select(i => i.Name).ToList();
    12 
    13             Type entityType = entity.GetType();
    14             var table = entityType.GetProperties().Where(i =>
    15                 !pkList.Contains(i.Name)
    16                 && i.GetValue(entity, null) != null
    17                 && i.PropertyType != typeof(EntityState)
    18                 && !(i.GetCustomAttributes(false).Length > 0
    19                 && i.GetCustomAttributes(false).Where(j => j.GetType() == typeof(NavigationAttribute)) != null)
    20                 && (i.PropertyType.IsValueType || i.PropertyType == typeof(string)) //过滤导航属性
    21                  ).ToArray();
    22 
    23             //过滤主键,航行属性,状态属性等
    24             if (pkList == null || pkList.Count == 0)
    25                 throw new ArgumentException("The Table entity have not a primary key.");
    26             List<object> arguments = new List<object>();
    27             StringBuilder builder = new StringBuilder();
    28 
    29             foreach (var change in table)
    30             {
    31                 if (pkList.Contains(change.Name))
    32                     continue;
    33                 if (arguments.Count != 0)
    34                     builder.Append(", ");
    35                 builder.Append(change.Name + " = {" + arguments.Count + "}");
    36                 if (change.PropertyType == typeof(string) || change.PropertyType == typeof(DateTime))
    37                     arguments.Add("'" + change.GetValue(entity, null).ToString().Replace("'", "char(39)") + "'");
    38                 else
    39                     arguments.Add(change.GetValue(entity, null));
    40             }
    41 
    42             if (builder.Length == 0)
    43                 throw new Exception("没有任何属性进行更新");
    44 
    45             builder.Insert(0, " UPDATE " + string.Format("[{0}]", entityType.Name) + " SET ");
    46 
    47             builder.Append(" WHERE ");
    48             bool firstPrimaryKey = true;
    49 
    50             foreach (var primaryField in pkList)
    51             {
    52                 if (firstPrimaryKey)
    53                     firstPrimaryKey = false;
    54                 else
    55                     builder.Append(" AND ");
    56 
    57                 object val = entityType.GetProperty(primaryField).GetValue(entity, null);
    58                 builder.Append(GetEqualStatment(primaryField, arguments.Count));
    59                 arguments.Add(val);
    60             }
    61             return new Tuple<string, object[]>(builder.ToString(), arguments.ToArray());
    62 
    63         }
    复制代码

    而对子类公开的Update方法,我们进行了一个封装,它通过操作枚举来确实你是要insert,update还是delete,看代码

    复制代码
     1         /// <summary>
     2         /// 执行SQL,根据SQL操作的类型
     3         /// </summary>
     4         /// <typeparam name="TEntity"></typeparam>
     5         /// <param name="list"></param>
     6         /// <param name="sqlType"></param>
     7         /// <returns></returns>
     8         protected string DoSQL<TEntity>(IEnumerable<TEntity> list, SQLType sqlType) where TEntity : class
     9         {
    10             StringBuilder sqlstr = new StringBuilder();
    11             switch (sqlType)
    12             {
    13                 case SQLType.Insert:
    14                     list.ToList().ForEach(i =>
    15                     {
    16                         Tuple<string, object[]> sql = CreateInsertSQL(i);
    17                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
    18                     });
    19                     break;
    20                 case SQLType.Update:
    21                     list.ToList().ForEach(i =>
    22                     {
    23                         Tuple<string, object[]> sql = CreateUpdateSQL(i);
    24                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
    25                     });
    26                     break;
    27                 case SQLType.Delete:
    28                     list.ToList().ForEach(i =>
    29                     {
    30                         Tuple<string, object[]> sql = CreateDeleteSQL(i);
    31                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
    32                     });
    33                     break;
    34                 default:
    35                     throw new ArgumentException("请输入正确的参数");
    36             }
    37             return sqlstr.ToString();
    38         }
    复制代码

     

    出处:http://www.cnblogs.com/lori/ 欢迎转载
  • 相关阅读:
    数据库——事务
    数据库——连接池
    JDBC——使用jdbc操作时,如何提取数据的性能
    2019-06-26 The Eclipse executable launcher was unable to locate its companion launcher
    2019-06-24在windows下如何查看80端口占用情况?是被哪个进程占用
    2019-06-19_解决ActiveMQ访问出现503的错误
    2019-06-17 tomcat启动;zookeeper启动批处理
    2019-06-13记忆 长命令
    2019-06-13linux的vi编辑器中如何查找关键字
    2019-06-13-vim配色步骤
  • 原文地址:https://www.cnblogs.com/harmonyboy/p/6061100.html
Copyright © 2011-2022 走看看