EF架構~為BulkInsert引入SET IDENTITY_INSERT ON功能(neng)
在設(she)計表(biao)結構時,我(wo)們(men)通常(chang)將不(bu)是(shi)很在乎表(biao)現(xian)的(de)主鍵設(she)計成自增長(chang)的(de),大(da)數據量用(yong)bigint,一(yi)般地用(yong)int就可以了,int就是(shi)C#里的(de)Int32,它最(zui)大(da)可以存儲到2147483647,21億,基本(ben)可以滿(man)足大(da)多數的(de)要求(qiu)了,呵呵。
對(dui)于自(zi)(zi)增長主(zhu)鍵來說(shuo),導數據(ju)(ju)是個比(bi)較麻(ma)煩的(de)事,使用(yong)SQLSERVER還(huan)可以,你把自(zi)(zi)增去了(le)(le),再(zai)進(jin)行(xing)SQL專入(ru)即可,但如果導數據(ju)(ju)這個動作是作到(dao)程序里,那可就有點麻(ma)煩了(le)(le),一般(ban)地,我們為自(zi)(zi)增主(zhu)鍵數據(ju)(ju)表導數據(ju)(ju)時,有兩個方式,一是去掉自(zi)(zi)增長特(te)性(xing),二是使用(yong)SQL提(ti)交的(de)SET IDENTITY_INSERT [table] ON/OFF,如果你的(de)導數據(ju)(ju)動作是在程序里完成的(de),那就只能(neng)使用(yong)后(hou)者(zhe)了(le)(le),沒人愿(yuan)意總(zong)是去手動改數據(ju)(ju)表結構,呵(he)(he)呵(he)(he)。
下(xia)面是(shi)我將(jiang)我的架構(gou)又(you)完善(shan)了(le)一下(xia),為(wei)BulkInsert方法重構(gou)了(le)一個 BulkInsert(IEnumerable<TEntity> item, bool isRemoveIdentity),即(ji)在批量插入數(shu)據(ju)時,可以選擇是(shi)否(fou)關閉自增特性,而手(shou)動(dong)為(wei)主(zhu)鍵賦(fu)值的方式,這(zhe)個對于有些導數(shu)據(ju)的場合非常重要。
看我的代碼吧:
public void BulkInsert(IEnumerable<TEntity> item, bool isRemoveIdentity) { string startTag = "", endTag = ""; if (isRemoveIdentity) { startTag = "SET IDENTITY_INSERT " + typeof(TEntity).Name + " ON;"; endTag = "SET IDENTITY_INSERT " + typeof(TEntity).Name + " OFF;"; } DataPageProcess(item, (currentItems) => { _Db.Database.Connection.Open(); ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超時(shi) _Db.Database.ExecuteSqlCommand(startTag + DoSQL(currentItems, SQLType.Insert) + endTag); }); }
注意:這里的SET IDENTITY_INSERT ON必(bi)須和你(ni)的SQL語(yu)句寫在(zai)一(yi)起,這樣(yang)它對于SQL來(lai)說(shuo)才是(shi)一(yi)個會話(hua)(hua),如果有(you)在(zai)一(yi)個會話(hua)(hua)里,你(ni)的SET IDENTITY_INSERT ON才有(you)意(yi)思,網上不(bu)(bu)少朋友(you)提倡(chang)使用TransactionScope,這一(yi)點我只有(you)一(yi)個建(jian)議,就是(shi)如果你(ni)的事務有(you)可(ke)能提升為MSDTC,那么,盡(jin)量不(bu)(bu)要(yao)用,呵呵。