Entity Framework และการหลีกเลี่ยง Anemic Domain Model


11

ในตรรกะทางธุรกิจของเราบางครั้งเรามีวิธีการที่กำหนดไว้ดังนี้:

User.ResetCourse(Course courseToReset)

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

เพื่อแก้ปัญหานี้เราเปลี่ยนลายเซ็นเป็น:

User.ResetCourse(MyDBContext db, Course courseToReset)

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

หลังจากนั้นเราย้ายไปยังชั้นบริการที่ให้ผู้ใช้ซึ่งหมายความว่าเรามีสิ่งที่ชอบ:

CourseService.ResetForUser(Course courseToReset, User forUser)

บริการนี้มีการอ้างอิงถึง DBContext ที่ถูกสร้าง แต่ตอนนี้วัตถุธุรกิจของเราเป็นเพียงถุงข้อมูลที่ไม่มีพฤติกรรม (เช่นรุ่น Anemic Domain Model)

เราจะหลีกเลี่ยงสิ่งนี้ได้อย่างไร


11
เสียงเหมือนที่คุณเพิ่งรู้ว่าโมเดลเอนทิตี้ของเฟรมเวิร์กนั้นเป็น DTO จริง ๆ และไม่ใช่โมเดลโดเมนเลย คุณพยายามทำ DDD จริงหรือไม่? ถ้าไม่มันอาจไม่สำคัญ
Mr Cochese

3
บริการ ADM plus เป็นสถาปัตยกรรมที่ดีสำหรับสิ่งต่าง ๆ มากมาย
Ewan

1
ที่เกี่ยวข้อง: ADM ไม่ได้เป็นรูปแบบการป้องกันก็คือการออกแบบ
John Wu

2
@ JohnWu เป็นบทความที่มีอคติมาก อันที่จริงมันมีรุ่น "Strawman" ของรูปแบบโดเมนที่หลากหลายโดยรวมถึงรูปแบบ Active Record ในตัวอย่างที่หลากหลาย แน่นอน Active Record ไม่ได้รับการสนับสนุนใน DDD และโดยทั่วไปเป็นตัวเลือกที่แย่สำหรับแอปพลิเคชันที่ซับซ้อนใด ๆ
RibaldEddie

คำตอบ:


8

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

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


0

คุณสามารถหลีกเลี่ยงได้โดยทำสิ่งที่ชอบ:

CourseService.prepareForUserCourseReset(DBContext db);
User.reset();
Course.reset();
CourseService.completeUserCourseReset(DBContext db);

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


-1

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

Udi Dahan เขียนบทความที่อธิบายถึงวิธีการทั่วไปซึ่งสามารถปรับให้เข้ากับ Entity Framework

http://udidahan.com/2007/09/16/fetching-strategy-nhibernate-implementation-available/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.