У меня есть 2 таблицы (для простоты многие поля удалены)
tblOrder - OrderId - OrderDate - UserId
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
}
}
}
Но это не кажется самым элегантным решением:
Потому что мне нужно перебирать каждый элемент в таблицах, чтобы установить идентификатор, а затем сохранить пакет.
Потому что из-за ошибки я теряю идентификатор в своей базе данных. (т.е. при первом сохранении, если произошла ошибка, OrderId = 1 теряется, а следующий OrderId будет 2)
Не масштабируется для очень больших транзакций с другой подтаблицей. В этом решении я построил пример с таблицей заказов и таблицей сведений о заказах, но в моем реальном приложении есть два других уровня под OrderDetail OrderDetailCreditMember и OrderDetailCreditCompany, где при любой покупке крошечная сумма зачисляется на счет участника и компании ( несколько строк), поэтому я могу получить дерево с 1 заказом, которое имеет 2 детали заказа, и каждая деталь заказа имеет 2 кредита участника и 3 кредита компании.
Так есть ли у кого-нибудь лучший способ сделать это.