zoukankan      html  css  js  c++  java
  • InsertOnSubmit、InsertAllOnSubmit等区别 (转)

    a. InsertOnSubmit: 将一个实体添加到datacontext对象中,并在SubmitChange()的时候执行更改。

    b. InsertAllOnSubmit:将一个实体集合添加到datacontext对象中,并在SubmitChange()的时候执行更改。

    例:

            UsersDataContext dal = new UsersDataContext();

            User[] user = new User[3]

            {

                new User { UserName = "Lily", UserPass = "Lily" },

                new User { UserName = "Lucy", UserPass = "Lucy" },

                new User { UserName = "Tom", UserPass = "Tom" },

            };

            User user1 = new User { UserName = "Bill", UserPass = "Bill" };

     

            dal.Users.InsertAllOnSubmit(user);//添加实体集合

            dal.Users.InsertOnSubmit(user1);//添加单个实体

       dal.SubmitChanges();

    以上结果为向数据库Users表中增加数据。

    ※注:以上两个函数必须要跟随SubmitChange()函数才能提交到数据库中。我们可以通俗的理解为:以上两个函数仅仅相当于一条Sql语句,而SubmitChange()相当于执行此条Sql语句。


    DeleteAllOnSubmit和InsertAllOnSubmit传进去的参数是一个继承IEnumerable接口的集合,当你调用SubmitChanges()的时候,整个集合会被删除(添加);
    DeleteOnSubmit和InsertOnSubmit传进去的参数是一个Object对象,调用SubmitChanges()时对单个对象进行删除(添加)

       无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和 InsertAllOnSubmit,前者是将一个实体标记为一个插入状态,而后都是将一个集合标记为插入状态,... 

          无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和 InsertAllOnSubmit,前者是将一个实体标记为一个插入状态,而后都是将一个集合标记为插入状态,而当前进行这两种操作时,你并没有与数据 库进行连接,这就是LINQ提倡的延时加载,那它们什么时候与数据库进行真正的交互呢,实现上,实验表明,是在触发SubmitChanges方法时,才 会真实与数据库进行操作,这是正常的,也没有什么可以说的。

         而今天我主要说的就是,当我们进行批量插入时,用linq给我们提供的InsertAllOnSubmit方法是否可以实现我们的操作,如果实现了,那是否是我们能够接受的方式,我们在做一个实验吧

    一个列表:

    List userList=new List();
                        
     for(int i=0;i<100000;i++)
     {
       userList.Add(new User{Name="zzl"+i});
     }
     _db.InsertAllOnSubmit(userList);
                        
    _db.SubmitChanges();


    结果怎么样呢?经过我的观察,结果是正确的,10万条数据可以插入到数据库中,LINQ确实是帮助我们完成了列表的插入工作,但过程我们是否可以接受?

    可以肯定的说,不可以,而且是非常不可以,对于这个插入操作,它对数据服务器的压力是惊人的,它建立“链接”次为10万次,即每个Insert语句就建立一个链接,这是我们不能接受的,所以,LINQ的批量操作确实靠不住。
    OK,既然LINQ的方式是不可取的,那我们只好自己去动手写了,呵呵,我们的思想去将10条Insert合并在一起,一次性发给服务器,一次性执行,对于目前的网络带宽这10条数据不成问题,呵呵。

    一 单个实体的Insert,我们采用LINQ的延时插入方式:

    public virtual void Insert(TEntity entity) where TEntity : class
           {
              DB.GetTable().InsertOnSubmit(entity);
               this.SubmitChanges();
          }

    二 批量插入实体,我们采用拼接字符串,并向数据服务器发命令的方式,这个也是我比较满足的作品,它是一个通用的方式,并且不需要修改原来插入代码,它的

    方法签名是一个列表,这样做是正确的,对于程序员来说是非常友好的。

    先看之前的LINQ批量插入:


    public virtual void Insert(IEnumerable list) where TEntity : class
           {
               DB.GetTable().InsertAllOnSubmit(list);
               this.SubmitChanges();
           }
    而在我们修改后,方法签名是不变的,所以原来调用它的方法,不需要进行修改:


    1         ///


    2         /// ADO优化的批量添加
    3         ///


    4         ///


    5         ///


    6         public virtual void Insert

    (IEnumerable list) where TEntity : class 
    7         {
    8             this.InsertForADO(list);
    9         }
    所需要的辅助方法:


    1 #region LINQ调用T-SQL实现批量添加
    2         ///
    3         /// 得到数据库表或视图的抽象
    4         ///
    5         ///
    6         ///
    7         MetaTable GetMetaTable(Type rowType)
    8         {
    9             return DB.Mapping.GetTable(rowType);
    10         }
    11
    12         ///
    13         /// 建立SQL语句
    14         ///
    15         ///
    16         ///
    17         Tuple CreateInsertArguments(TEntity entity)
    18         {
    19             if (entity == null)
    20                 throw new ArgumentException("The database entity can not be null.");
    21
    22             Type entityType = entity.GetType();
    23             MetaTable table = GetMetaTable(entityType);
    24             MetaDataMember identityDatamember = table.RowType.DBGeneratedIdentityMember;
    25
    26             List arguments = new List();
    27             StringBuilder fieldbuilder = new StringBuilder();
    28             StringBuilder valuebuilder = new StringBuilder();
    29
    30             fieldbuilder.Append("INSERT INTO " + table.TableName + " (");
    31
    32             foreach (var member in table.RowType.PersistentDataMembers)
    33             {
    34
    35                 if (!member.IsAssociation && !member.IsDbGenerated)
    36                 {
    37                     object value = entityType.GetProperty(member.Name).GetValue(entity, null);
    38                     if (value != null)
    39                     {
    40                         if (arguments.Count != 0)
    41                         {
    42                             fieldbuilder.Append(", ");
    43                             valuebuilder.Append(", ");
    44                         }
    45
    46                         fieldbuilder.Append(member.MappedName);
    47                         if (member.Type == typeof(string) || member.Type == typeof(DateTime))
    48                             valuebuilder.Append("'{" + arguments.Count + "}'");
    49                         else
    50                             valuebuilder.Append("{" + arguments.Count + "}");
    51                         if (value.GetType() == typeof(string))
    52                             value = value.ToString().Replace("'", "char(39)");
    53                         arguments.Add(value);
    54
    55                     }
    56                 }
    57             }
    58
    59
    60             fieldbuilder.Append(") Values (");
    61
    62             fieldbuilder.Append(valuebuilder.ToString());
    63             fieldbuilder.Append(");");
    64             return new Tuple(fieldbuilder.ToString(), arguments.ToArray());
    65         }
    66
    67         void InsertForADO(IEnumerable list)
    68         {
    69             StringBuilder sqlstr = new StringBuilder();
    70             list.ToList().ForEach(i =>
    71             {
    72                 Tuple insert = CreateInsertArguments(i);
    73                 sqlstr.AppendFormat(insert.Item1, insert.Item2);
    74             });
    75             DB.ExecuteCommand(sqlstr.ToString());
    76         }
    77
    78         #endregion



           
           169IT站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    博文来源广泛,如原作者认为我侵犯知识产权,请尽快给我发邮件 664507902@qq.com联系,我将以第一时间删除相关内容。

查看全文
  • 相关阅读:
    第8/24周 覆盖索引 临界点
    理解统计信息(1/6):密度向量
    索引碎片检测
    索引碎片
    索引深入浅出(10/10):创建索引时,键列位置的重要性
    索引深入浅出(9/10):过滤索引
    索引深入浅出(8/10):覆盖索引或列包含
    索引深入浅出(7/10):非唯一列上的非聚集索引
    索引深入浅出(6/10):选择正确并合适的聚集索引键
    索引深入浅出(5/10):非聚集索引的B树结构在堆表
  • 原文地址:https://www.cnblogs.com/ooip/p/4721390.html
  • Copyright © 2011-2022 走看看