[英]Best practice for inserting/updating data in multiple tables at once
因此,我的數據庫中有兩個表,即“聯系人”和“地址”:
聯系人 :ContactID | 地址ID | 名| 姓
地址 :AddressID | 地址1 | 地址2 | 城市| 州| 郵政編碼
我有一個頁面,您可以在其中添加聯系人。 它包含聯系人的所有信息和聯系人的地址。 這是我提交表單時的代碼:
[HttpPost]
public ActionResult Edit(ContactsViewModel viewModel)
{
//if editing an contact, fetch it; otherwise, create a new one
Contact contact = viewModel.ContactId == 0
? new Contact()
: _adminRepository.GetContact(viewModel.ContactId);
TryUpdateModel(contact);
if (ModelState.IsValid)
{
_adminRepository.SaveAddress(contact.Address);
_adminRepository.SaveContact(contact);
return RedirectToAction("Index");
}
return View(viewModel); // validation error, so redisplay same view
}
現在,我主要關心的是地址已成功添加,但是當我嘗試保存聯系人時出現錯誤,該地址在數據庫中沒有聯系人。
在發生錯誤時回滾所有更改的最佳實踐是什么?
那應該是一種方法,而不是兩種 。
如果一個地址總是與一個聯系人相關(看起來就是這樣),那么您應該只有一個存儲庫-例如ContactRepository 。
每個聚合根都應該有一個存儲庫,或者用簡單的術語來說-每個需要單獨檢索的實體的存儲庫。
我不知道_adminRepository
是什么,但是我認為您只是有一個SaveContact(contact)
方法。
您是否正在使用像實體框架這樣的ORM? 如果是這樣,則兩次插入都將在一個事務中完成(由EF處理),因此如果一次插入失敗,則兩次插入都會失敗。
如果您開始對多個存儲庫/聚合根進行更改,則將需要諸如Unit或TransactionScope之類的東西。
因此,聽起來您需要重新考慮存儲庫設計。 對於單個聚合實體(聯系人),應該有一個通用的Save方法,而不是為每個關系單獨使用。
“工作單元”模式是針對db上的多個操作(也可以是其他操作)的一種不錯的且可接受的解決方案,請閱讀Entity Framework博客程序經理Faisal Mohamood的樣本。
您需要在存儲庫中使用TransactionScope()。 查看MSDN論壇條目 。 第一個答復顯示了一個將其集成到方法中的簡單示例。 關鍵是沒有它,就無法專門回滾更改。
我的偏好是制作一個存儲過程來插入兩條記錄。 您可以使用TSQL事務。 使用TransactionScope()也可以,因此該決定可能應該基於您的數據訪問層。 如果您已經在使用許多SPROC,請通過事務處理制作一個復雜的SPROC。
如果您使用的是Entity Framework(...很痛苦!!!!),那么.net TransactionScope()會更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.