I have 2 tables (For simplicity many field where removed)
tblOrder - OrderId - OrderDate - UserId
tblOrderDetail - OrderDetailId - OrderId - ProductId - Qantity
I go ahead and create my object and I want to save everything in memory in one transaction because if something fail in the order details, I don't want the order to be saved. I use the following code, but I don't understand how to properly do it in one transaction.
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);
// Only two for test purpose.
Now I could easily do this
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
}
}
}
But this does not seem the most elegant solution:
Because I have to iterate through each items in the tables to set the ID and then save the batch.
Because on error, I loose an ID in my database. (i.e. on first save if an error occured, OrderId = 1 is lost and next OrderId will be 2)
Not scalable for very large transaction with another sub table. In this solution I built the exemple with an Order table and an Order Detail table but in my real application, there are two other levels unders OrderDetail OrderDetailCreditMember and OrderDetailCreditCompany where on any purchase, a tiny amount is credited to the member and to the company (multiple rows) so I can end up having a tree with 1 order that has 2 order details and each order details has 2 member credits and 3 company credits.
So does anyone have a better way of doing this.