งูเห่า. NET MVC: การแมปเอนทิตีเพื่อดูโมเดล

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

IList<Contact> contacts;

using (IContactRepository repository = new ContactRepository())
{
    contacts = repository.Fetch().ToList();
}

EditContactViewModel vm = new EditContactViewModel(contacts);

return View(vm);

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

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

เทคนิคใดที่เป็น/เหมาะสมที่สุดในการเอาชนะข้อกังวลของฉัน?


person senfo    schedule 15.02.2010    source แหล่งที่มา


คำตอบ (2)


Automapper จะทำงานให้กับกรณีของคุณ สิ่งที่คุณมีคือกราฟวัตถุ สิ่งของมีบางอย่างมากกว่านั้น ซึ่ง Automapper จัดการได้ดี

person John Farrell    schedule 15.02.2010
comment
เจ๋งมาก. ฉันยังใหม่กับ AutoMapper ดังนั้นฉันจึงไม่รู้ด้วยซ้ำว่ามันสามารถแมปแบบนั้นได้ ขอบคุณมาก. - person senfo; 16.02.2010

จัดการข้อกังวลเหล่านี้เพื่อ...

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

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

โดยส่วนตัวแล้ว ฉันมีวิธีการในคลาสคอนโทรลเลอร์พื้นฐานซึ่งมีลักษณะดังนี้:

protected T AddDisposable<T>(T disposable) where T : class, IDisposable
{
    // Error checking.
    if (disposable == null) throw new ArgumentNullException("disposable");

    // Add to list
    ...
}

โดยพื้นฐานแล้ว จะช่วยให้คุณสามารถจัดเก็บการใช้งาน IDisposable จากนั้นในการใช้งาน IDisposable ของคอนโทรลเลอร์ มันจะวนซ้ำผ่านรายการ และกำจัดทุกอย่าง

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

อย่างไรก็ตาม ฉันไม่เห็นด้วยหากคุณไม่ต้องการให้มี เพราะคุณต้องการเน้นไปที่ประเภทใดประเภทหนึ่งในคอนโทรลเลอร์ทีละตัว ฯลฯ

ด้วยเหตุนี้ คุณจะต้องสร้าง Data Transfer Objects ซึ่งโดยทั่วไปจะแมประหว่างประเภทที่คุณเปิดเผยในโมเดลมุมมองและโมเดลเอนทิตีของคุณ

person casperOne    schedule 15.02.2010