2009-09-03 22 views
0

我有2個表(爲了簡化許多領域,其中移除)如何使用亞音速交易與親子表

tblOrder - 的OrderId - 訂購日期 - 用戶ID

tblOrderDetail - OrderDetailId - 的OrderId - ProductId - Qantity

我繼續創建我的對象,並且我想將所有內容保存在一個事務中,因爲如果訂單詳情中有些內容失敗,我不希望訂單被保存。我使用下面的代碼,但我不明白如何在一個事務中正確執行它。

Order newOrder = new Order(); 
OrderDetailCollection newOrderDetails = new OrderDetailCollection(); 
OrderDetail newOrderDetail; 

newOrder.OrderDate = DateTime.Now(); 
newOrder.UserId = 1; 

newOrderDetail = new OrderDetail(); 
// newOrderDetail.OrderId = newOrder.OrderId; // Can't do that yet, newOrder is not saved and OrderId is Null. 
newOrderDetail.ProductId = 1; 
newOrderDetail.Quantity = 25; 

newOrderDetails.Add(newOrderDetail); 

newOrderDetail = new OrderDetail(); 
// newOrderDetail.OrderId = newOrder.OrderId; // Can't do that yet, newOrder is not saved and OrderId is Null. 
newOrderDetail.ProductId = 1; 
newOrderDetail.Quantity = 25; 

newOrderDetails.Add(newOrderDetail); 

//只有兩個用於測試目的。

現在,我可以很容易地做到這一點

using (System.Transactions.TransactionScope ts = new TransactionScope()) {  
    using (SharedDbConnectionScope scs = new SharedDbConnectionScope()) { 
     try { 
     newOrder.Save(); 

     foreach(OrderDetail anOrderDetail in newOrderDetails) { 
      anOrderDetail.OrderId = newOrder.OrderId; 
     } 

     newOrderDetails.BatchSave(); 

     ts.Complete(); 
     }   
     catch (Exception ex) { 
     //Do stuff with exception or throw it to caller 
     } 
    } 
} 

但是,這似乎是最優雅的解決方案並不:

  1. 因爲我必須通過表中的每個項目重複設置的ID和然後保存該批次。

  2. 因爲出錯,我在我的數據庫中丟失了一個ID。 (即如果發生錯誤首先保存,OrderId = 1丟失,並且下一個OrderId將爲2)

  3. 對於使用另一個子表的超大事務不可伸縮。在這個解決方案中,我使用Order表和Order Detail表構建了一個例子,但在我的真實應用程序中,OrderDetail OrderDetailCreditMember和OrderDetailCreditCompany有兩個其他級別,在任何購買的情況下,少量金額記入會員和公司多行),所以我最終可以得到一棵有1個訂單的樹,其中有2個訂單明細,每個訂單明細有2個會員積分和3個公司積分。

那麼沒有人有更好的方式來做到這一點。

回答

2

說實話,我認爲你可能會過早地在這裏優化。

  1. 因爲我必須遍歷表中的每個項目來設置ID,然後保存批處理。

你在內存中迭代你只有兩個SQL調用在你的事務中,對我來說似乎沒有太大的效率。

  1. 因爲錯誤,我在我的數據庫中丟失了一個ID。 (即在第一次保存,如果有錯誤發生,的OrderId = 1丟失,接下來的OrderId會2)

這真的是一個問題,如何將經常你期望發生的錯誤,我假設你」在你試圖保存它們之前重新驗證你的對象,所以它真的應該是非常罕見的,你會得到一個錯誤(例如無法連接到數據庫),所以我不相信這是一個問題。如果您遇到了很多錯誤,這是需要單獨解決的問題。

  1. 對於使用另一個子表的超大型事務不可伸縮。在這個解決方案中,我使用Order表和Order Detail表構建了一個例子,但在我的真實應用程序中,OrderDetail OrderDetailCreditMember和OrderDetailCreditCompany有兩個其他級別,在任何購買的情況下,少量金額記入會員和公司多行),所以我最終可以得到一棵有1個訂單的樹,其中有2個訂單明細,每個訂單明細有2個會員積分和3個公司積分。

是的,這裏可能會出現縮放問題,但您在討論1 x 2 x 2 x 3 = 12個循環的內存循環和3個SQL調用。除非你經常發生這種情況,否則這真的不應該是太大的問題。你多久會期待這種方法被調用?