?
当前位置:??编程语言>c#/asp.net

Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍

?
分享到:
????发布时间:2014-1-12??


????本文导语:? 无论是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





  • 本站(WWW.169IT.COM)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.169IT.COM)站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.
    转载请注明:文章转载自:[169IT-IT技术资讯]
    本文标题:Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍
相关文章推荐:


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

?2012-2019,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号