ด้วย Entity Framework เวลาส่วนใหญ่SaveChanges()
ก็เพียงพอแล้ว สิ่งนี้จะสร้างทรานแซคชันหรือ enlist ในทรานแซคชันใด ๆ และทำงานที่จำเป็นทั้งหมดในทรานแซคชันนั้น
บางครั้งแม้ว่าการSaveChanges(false) + AcceptAllChanges()
จับคู่จะมีประโยชน์
สถานที่ที่มีประโยชน์ที่สุดสำหรับสิ่งนี้คือในสถานการณ์ที่คุณต้องการทำธุรกรรมแบบกระจายในบริบทที่แตกต่างกันสองแห่ง
เช่นนี้ (ไม่ดี):
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save and discard changes
context1.SaveChanges();
//Save and discard changes
context2.SaveChanges();
//if we get here things are looking good.
scope.Complete();
}
หาก context1.SaveChanges()
ประสบความสำเร็จ แต่context2.SaveChanges()
ล้มเหลวการทำธุรกรรมการกระจายทั้งหมดจะถูกยกเลิก แต่น่าเสียดายที่ Entity Framework ยกเลิกการเปลี่ยนแปลงไปcontext1
แล้วดังนั้นคุณจึงไม่สามารถเล่นซ้ำหรือบันทึกความล้มเหลวได้อย่างมีประสิทธิภาพ
แต่ถ้าคุณเปลี่ยนรหัสของคุณเป็นดังนี้:
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Do something with context2
//Save Changes but don't discard yet
context1.SaveChanges(false);
//Save Changes but don't discard yet
context2.SaveChanges(false);
//if we get here things are looking good.
scope.Complete();
context1.AcceptAllChanges();
context2.AcceptAllChanges();
}
ในขณะที่การเรียกเพื่อSaveChanges(false)
ส่งคำสั่งที่จำเป็นไปยังฐานข้อมูลบริบทจะไม่เปลี่ยนแปลงดังนั้นคุณสามารถทำได้อีกครั้งหากจำเป็นหรือคุณสามารถสอบถามObjectStateManager
หากคุณต้องการ
ซึ่งหมายความว่าถ้าการทำธุรกรรมเกิดข้อยกเว้นจริงคุณสามารถชดเชยได้โดยลองใหม่หรือเข้าสู่ระบบสถานะของแต่ละบริบทObjectStateManager
ที่ไหนสักแห่ง
ดูโพสต์บล็อกของฉัน มากขึ้น
SaveChanges(fase); ... AcceptAllChanges();
รูปแบบในตอนแรก โปรดสังเกตว่าคำตอบที่ได้รับการยอมรับสำหรับคำถามข้างต้นเขียนโดยผู้เขียนบล็อก และบล็อกนั้นอ้างอิงในคำถามอื่น ทุกอย่างมารวมกัน