NHibernate และการยกเลิกการเปลี่ยนแปลงเอนทิตี

ดูเหมือนว่าจะเป็นปัญหาทั่วไป แต่ฉันไม่ทราบวิธีแก้ปัญหาที่ดีที่สุด ฉันต้องการที่จะส่งเอนทิตีไปยังมุมมอง มีการเปลี่ยนแปลงกับเอนทิตีในมุมมอง แต่จากนั้นยกเลิก (ลบ) การเปลี่ยนแปลงเหล่านั้นหากผู้ใช้ยกเลิกออกจากมุมมอง วิธีที่เหมาะสมในการทำเช่นนี้คืออะไร

นี่คือสองตัวเลือกที่ฉันมี แต่ฉันคิดว่าควรมีตัวเลือกอื่นที่ดีกว่า

1) นำเอนทิตี สร้างโคลน ส่งโคลนไปที่มุมมอง...หากยอมรับการเปลี่ยนแปลง ให้อัปเดตเอนทิตีดั้งเดิมด้วยค่าของโคลน

2) ส่งเอนทิตีไปยังมุมมอง หากผู้ใช้ยกเลิก ให้ลบเอนทิตีออกจากแคชของ NHibernate แล้วโหลดซ้ำจากฐานข้อมูล

สำหรับ (2) ปัญหาสำหรับฉันคือยังคงสามารถอ้างอิงเอนทิตีเก่าได้ตลอดทั้งโปรเจ็กต์ของฉัน หลังจากที่ถูกลบออกจากแคชแล้ว

แก้ไข:

ตกลง ดังนั้นวิธีขับไล่คือหนทางที่จะไปหากฉันกำลังใช้วิธี (2) ขอบคุณครับ จำรายละเอียดไม่ได้แล้ว อย่างไรก็ตาม ปัญหาของการดูออบเจ็กต์ที่อ้างอิงถึงเอนทิตีเก่าของฉันที่ถูกขับไล่ ทำให้ปัญหานี้ยากต่อการจัดการ ฉันไม่สามารถให้มุมมองของฉันอัปเดตเป็นเอนทิตีใหม่โดยอัตโนมัติโดยไม่ต้องมีโค้ดที่กำหนดเองในแต่ละรายการเพื่อเชื่อมโยงใหม่เมื่อเหตุการณ์การขับไล่แบบกำหนดเองของฉันถูกหยิบยกขึ้นมา และการรีดิ้งอาจไม่เป็นเรื่องเล็กน้อยในบางกรณี ฉันต้องคิดเรื่องนี้ให้มากกว่านี้เพราะฉันอาจจะซับซ้อนเกินไป แต่ในขณะนี้ วิธีนี้ดูยุ่งยากกว่า

ฉันสงสัยว่าฉันจะติดอยู่กับวิธีที่ (1) ซึ่งมีปัญหาของตัวเอง แต่จะรออีกสักหน่อยเพื่อดูว่ามีใครมีแนวคิดบ้างไหม

แก้ไข 2: เพิ่งพบสิ่งนี้ ฉันคิดว่ามันครอบคลุมคำตอบในรายละเอียดค่อนข้างมาก และมาพร้อมกับโครงการสาธิตที่ยอดเยี่ยม - การสร้างแอปพลิเคชัน To-Do บนเดสก์ท็อปด้วย NHibernate - http://msdn.microsoft.com/en-us/นิตยสาร/ee819139.aspx

นอกจากนี้ NHibernate ยังมีฟังก์ชัน Session.Refresh(Object Entity) ซึ่งดูเหมือนว่าจะแก้ปัญหาได้ตรงจุด ดังนั้น เมื่อเอนทิตีมีการเปลี่ยนแปลงแต่ถูกยกเลิกก่อนที่จะบันทึก ฉันสามารถเรียก Session.Refresh เพื่อโหลดซ้ำจากฐานข้อมูลและละทิ้งการเปลี่ยนแปลง


person i8abug    schedule 30.03.2010    source แหล่งที่มา
comment
ปัญหาทั่วไปกับ Refresh เกิดขึ้นเมื่อเอนทิตีมีความสัมพันธ์แบบเรียงซ้อน จากนั้นรายการย่อยเหล่านั้น (เอนทิตีที่เกี่ยวข้อง) จะถูกรีเฟรชด้วย ซึ่งอาจทำให้เกิดผลกระทบต่อประสิทธิภาพที่เห็นได้ชัดเจน ฉันเพิ่งประสบปัญหาที่ฉันอธิบาย ดังนั้นข้อมูลนี้อาจช่วยเหลือผู้อื่นได้   -  person jweyrich    schedule 21.12.2015


คำตอบ (2)


ฉันจะเลือกตัวเลือกที่ 1 และใช้สิ่งที่เรียกว่า ViewModel แทนเอนทิตีของคุณ ViewModel เป็นตัวแทนของโมเดลของคุณสำหรับมุมมองเฉพาะ ใน ViewModel คุณสามารถผสมข้อมูลจากเอนทิตีต่างๆ และค่ารูปแบบล่วงหน้าเพื่อให้พอดีกับมุมมอง เป็นวิธีที่สวยงามในการส่งข้อมูลไปยังมุมมองและคุณสามารถบรรลุสิ่งที่คุณต้องการได้อย่างง่ายดาย

การใช้ ViewModels กำลังกลายเป็นวิธีที่นิยมในการทำงานใน ASP.net MVC และ Silverlight / WPF

หากต้องการอ่านเพิ่มเติมเกี่ยวกับ Viewmodels: http://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx

person Ariel Popovsky    schedule 30.03.2010
comment
ฉันลงเอยด้วยการใช้โซลูชันนี้บ้าง ฉันพบว่ามันไม่เหมาะนัก เพราะบางครั้งเอนทิตีของฉันมีสิ่งที่ควรอยู่ในมุมมองของฉัน และฉันไม่ชอบที่จะต้องคัดลอกคุณสมบัติของพวกเขาไปยังสิ่งอื่น ถึงกระนั้นก็ถือว่าโอเคเป็นส่วนใหญ่ ขอบคุณ - person i8abug; 14.10.2010
comment
ในที่สุดคุณจะชินกับมัน ฉันแนะนำให้ใช้ Automapper เพื่อบรรเทาความเจ็บปวดจากการคัดลอกข้อมูลไปมา automapper.codeplex.com - person Ariel Popovsky; 15.10.2010
comment
ในตอนแรกมันเจ็บปวด และความคิดที่จะนำประเภทที่สองไปใช้เพื่อให้คุณสามารถเปลี่ยนรูปร่างของโมเดล/ข้อมูลเป็นสิ่งที่เหมาะสมกับมุมมอง ทำให้ฉันอยากจะกรีดร้อง! - ฉันต่อสู้กับแนวคิดนี้มาเกือบปีแล้ว และในที่สุดก็ต้องเผชิญกับความจริงที่ว่า NH และ ASP.NET MVC ไม่ได้ออกแบบมาเพื่อแนวทางอื่นใด แม้ว่ามันจะทำให้คุณประจบประแจง แต่ฉันขอแนะนำอย่างยิ่งให้คุณลืม DRY และยอมรับการทำซ้ำในระดับสูง นั่นคือสิ่งที่เครื่องมือได้รับการออกแบบมา การว่ายทวนกระแสน้ำจะทำให้เกิดความเจ็บปวดและไม่มีรางวัลที่แท้จริง - person mindplay.dk; 23.02.2012

วิธีที่ดีที่สุดในการทำเช่นนี้คือการเรียกเมธอด Evict บน ISession ที่ใช้ในการโหลดออบเจ็กต์ การดำเนินการนี้จะลบวัตถุออกจากแคชเซสชัน จากนั้นคุณสามารถโหลดซ้ำและแสดงอีกครั้งได้

การลบออบเจ็กต์ออกจากเซสชันจะทำให้แยกออก ชั่วคราว ดังนั้นหากยังคงมีการอ้างอิงถึงวัตถุในโปรเจ็กต์ วัตถุเหล่านั้นจะไม่คงอยู่เมื่อเซสชันถูกล้าง วิธีที่คุณจัดการกับสิ่งนั้นขึ้นอยู่กับใบสมัครของคุณ แต่ฉันขอแนะนำให้จัดกิจกรรมเพื่อแจ้งให้สมาชิกทราบว่าพวกเขาจำเป็นต้องโหลดออบเจ็กต์อีกครั้ง

person Jamie Ide    schedule 30.03.2010