簡體   English   中英

Linq To Sql和identity_insert

[英]Linq To Sql and identity_insert

我正在嘗試在主鍵是Identity字段的表上執行記錄插入。

我試過打電話
mycontext.ExecuteCommand("SET identity_insert myTable ON")
但這沒有任何好處。

當我提交更改時,我收到一條錯誤,提示IDENTITY_INSERTOFF

我怎樣才能把它ON從C#代碼之前,我提交更改?

編輯

我已經讀過這是因為ExecuteCommand的代碼在不同的會話中執行。

編輯2

有沒有什么辦法可以執行一些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中

  • 自動生成值: 正確 ;
  • 自動同步: OnInsert ;
  • 主鍵: 正確 ;
  • 服務器數據類型: int NOT NULL IDENTITY ;
  • 輸入: int ;

每次添加新記錄時,只需簡單的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM