[英]Linq To Sql and identity_insert
我正在嘗試在主鍵是Identity
字段的表上執行記錄插入。
我試過打電話
mycontext.ExecuteCommand("SET identity_insert myTable ON")
但這沒有任何好處。
當我提交更改時,我收到一條錯誤,提示IDENTITY_INSERT
為OFF
。
我怎樣才能把它ON
從C#代碼之前,我提交更改?
我已經讀過這是因為ExecuteCommand的代碼在不同的會話中執行。
有沒有什么辦法可以執行一些DDL來從我的C#代碼中刪除身份規范,進行插入,然后重新打開身份規范?
另一種選擇是將所有Linq2Sql調用包裝在TransactionScope()中。 這應該強制它們在同一個連接中運行。
using System.Transactions; // Be sure to add a reference to System.Transactions.dll to your project.
// ... in a method somewhere ...
using (System.Transaction.TransactionScope trans = new TransactionScope())
{
using(YourDataContext context = new YourDataContext())
{
context.ExecuteCommand("SET IDENTITY_INSERT MyTable ON");
context.ExecuteCommand("yourInsertCommand");
context.ExecuteCommand("SET IDENTITY_INSERT MyTable OFF");
}
trans.Complete();
}
// ...
雖然,如果你想嘗試做類似的事情:
context.ExecuteCommand("SET IDENTITY_INSERT MyTable ON");
context.MyTable.InsertOnSubmit(myTableObject)
context.SubmitChanges()
context.ExecuteCommand("SET IDENTITY_INSERT MyTable OFF");
您可能會遇到其他問題,尤其是在標識列將IsDbGenerated屬性設置為true的情況下。 Linq2Sql生成的SQL命令不知道包含標識列和值。
您需要在單個T-SQL代碼塊中執行所有步驟 - 如果您想打開它,那么這將非常困難,然后執行您的LINQ-to-SQL查詢,然后將其關閉:(
我看到的唯一真正的解決方案是將整個SQL打包成SQL語句並執行:
SET IDENTITY_INSERT MyTable ON
(do your update here)
SET IDENTITY_INSERT MyTable OFF
並使用.ExecuteContext()
其作為單個代碼塊執行
渣
PS:對於你的編輯#2:不,不幸的是,沒有(簡單的)方法從列中刪除標識,並將其重新打開。 Basicall你必須創建一個沒有IDENTITY的新列,復制值,刪除IDENTITY列,然后在完成時向后執行相同操作 - 抱歉! :-(
PS#2:這真的引出了一個問題:到底要做什么需要做一個“身份插入”? 從應用程序定期? 當然 - 你可能會偶爾遇到這種需求,但我總是在SQL Mgmt Studio中單獨執行此操作 - 當然不在我的應用程序中.....(只是好奇你的用例/動機是什么)。
在執行命令之前,應該手動打開連接。 這使得命令在同一會話中運行:
context.Connection.Open();
context.ExecuteCommand("SET IDENTITY_INSERT MyTable ON");
// make changes
// ...
context.SubmitChanges();
我做的是這樣的(Nbuider用於創建實體)。 我通常創建所有行,除了標識插入行; 這最終完成了。 這是測試數據創建,因此不需要事務。
using (var entitiesEfContext = new ContextABC())
{
var platforms = Builder<Platform>
.CreateListOfSize(4)
.TheFirst(1)
.With(x => x.Description = "Desc1")
.With(x => x.IsDeleted = false)
.TheNext(1)
.With(x => x.Description = "Desc2")
.With(x => x.IsDeleted = false)
.TheNext(1)
.With(x => x.Description = "Desc3")
.With(x => x.IsDeleted = false)
.TheNext(1)
.With(x => x.Description = "Desc4")
.With(x => x.IsDeleted = false)
.Build();
foreach (var platform in platforms)
{
entitiesEfContext.Platform.AddObject(platform);
}
entitiesEfContext.SaveChanges();
// the identity insert row (o as id in my case)
entitiesEfContext.ExecuteStoreCommand("SET IDENTITY_INSERT Platform ON; INSERT INTO [Platform](Platformid,[Description],[IsDeleted],[Created],[Updated]) VALUES (0,'Desc0' ,0 ,getutcdate(),getutcdate());SET IDENTITY_INSERT Platform Off");
}
我有相同的錯誤消息。 我通過更改表中主鍵的屬性來解決它。
MyTable.MyId int IDENTITY(1,1) NOT NULL
屬性設置MyId(在dbml中 )
每次添加新記錄時,只需簡單的reseed identity key
(帶自定義ID),例如:
using (var desDb = new DesDbContext())
{
// del-table-all --------------------------------------------------------
desDb.Database.ExecuteSqlCommand("DELETE FROM [Products]");
foreach (var desItem in desList) //desList is List of Product
{
// reseed identity key
desDb.Database.ExecuteSqlCommand("DBCC CHECKIDENT('Products', RESEED,"
+ (desItem.ProductID - 1) + ");");
// and record
desDb.Products.Add(desItem);
// save-db
desDb.SaveChanges();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.