2013-07-08 61 views
46

實體框架 - 在調用'SaveChanges'之前是否有任何方法在事務內部檢索新創建的ID(標識)?實體框架 - 在交易中的'SaveChanges'之前檢索ID

我需要一個第二個插入的ID,但它始終返回0 ...是由數據庫生成

 ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext; 

     objectContext.Connection.Open(); 

     using (var transaction = objectContext.Connection.BeginTransaction()) 
     { 
      foreach (tblTest entity in saveItems) 
      { 
       this.context.Entry(entity).State = System.Data.EntityState.Added; 
       this.context.Set<tblTest>().Add(entity); 

       int testId = entity.TestID; 

       .... Add another item using testId 
      } 

      try 
      { 
       context.SaveChanges(); 
       transaction.Commit(); 
      } 
      catch (Exception ex) 
      { 
       transaction.Rollback(); 
       objectContext.Connection.Close(); 
       throw ex; 
      } 
     } 

     objectContext.Connection.Close(); 
+3

http://stackoverflow.com/questions/6029711/id-of-newly-added-entity-before-savechanges – Zaki

+0

哦,希望有一種方式,但謝謝。 – user1948635

回答

38

的ID行插入到表後。在插入行之前,您無法向數據庫詢問該值。

你有兩種解決方法 - 最簡單的方法是撥打SaveChanges。由於您處於交易中,因此您可以回滾,以免在獲取ID後出現問題。

第二種方法不是使用IDENTITY內置的數據庫,而是自己實施它們。當你有很多批量插入操作時,這可能非常有用,但它帶有一個價格 - 實現起來並不是微不足道的。

編輯:SQL Server 2012有一個內置的SEQUENCE類型,可以用來代替IDENTITY列,不需要自己實現它。

+1

如果我在第一次插入後調用'SaveChanges',那麼第二次插入失敗 - 事務是否會將第一次插入返回? – user1948635

+6

當然,這就是交易的意義。事務中的每個操作都將在'rollback'上回滾。看看http://en.wikipedia.org/wiki/ACID – SeriousM

+0

實體中沒有回滾功能。它像雞和雞蛋的問題。唯一的方法是執行一些純SQL,然後向DB詢問下一個Identity將會是什麼。但是這是不能保證的,因爲有人可以接受它。另一件事是編寫SQL並插入和清空行來保留它,但是你可能會使用空的保留行。 – ppumkin

7

@zmbq是正確的,你只能在調用保存更改後才能得到id。

我的建議是你不應該依賴數據庫生成的ID。 數據庫應該只是你的應用程序的一個細節,而不是一個不可或缺的部分。

如果您無法解決該問題,請使用GUID作爲標識符,因爲它具有唯一性。 MSSQL支持GUID作爲本地列類型,並且速度很快(儘管不比INT快)。

乾杯

+0

不幸的是,現在更改ID字段會導致應用程序的其他方面出現問題,這意味着我試圖避免的重大更改。 – user1948635

+0

但它是一個INT列,對不對?也許你可以插入一個TICK或你自己創建的唯一號碼。 – SeriousM

+0

它是,但有大量的SSIS包運行在數據庫上期望一個標識列... – user1948635

3

如果您TBLTEST實體連接到您要附加其他實體,你不需要有ID來創建的關係。比方說TBLTEST連接到anotherTest對象,它的方式是,在anotherTest對象必須TBLTEST對象和tblTestId屬性,在這種情況下,你可以有這樣的代碼:

using (var transaction = objectContext.Connection.BeginTransaction()) 
    { 
     foreach (tblTest entity in saveItems) 
     { 
      this.context.Entry(entity).State = System.Data.EntityState.Added; 
      this.context.Set<tblTest>().Add(entity); 

      anotherTest.tblTest = entity; 
      .... 
     } 
    } 

提交的關係後,也可以創建和你不不需要擔心ID等