2012-03-27 37 views
7

Tôi có EF 4 được triển khai trong dự án. Trong đó, có bảng khách hàng và đặt hàng. Trong đó có mối quan hệ một (khách hàng) với nhiều (thứ tự).cách thiết kế ViewModel

Tôi đang tạo chế độ xem cho cả hai (CustomerViewModel và OrderViewModel) sẽ được chuyển từ lớp miền của tôi sang lớp giao diện (MVC trong trường hợp này).

Bây giờ câu hỏi là "làm tôi cần phải tham khảo cả viewmodel? Ví dụ như trong customerviewmodel có IEnumerable<OrderViewModel> và trong orderviewmodel có CustomerViewModel. Nếu vậy làm thế nào để thiết kế nó (như là một thực hành tốt nhất) để IEnumerable<OrderViewModel>CustomerViewModel là dân cư với

+0

Xem điều này có giúp ích: http://blogs.teamb.com/craigstuntz/2009/12/31/38500/ –

+0

xin lỗi không liên quan .. – user384080

Trả lời

23

Tôi sẽ luôn luôn lái thiết kế của ViewModels với quan điểm cụ thể trong tâm trí, không bao giờ từ quan điểm của mô hình miền (= các thực thể) .Một ViewModel trông phụ thuộc vào những gì bạn muốn hiển thị và những gì bạn muốn sửa đổi trong chế độ xem.

Kết quả là bạn không có THE OrderViewModel và THE CustomerViewModel vì bạn có các chế độ xem khác nhau sẽ hiển thị hoặc chỉnh sửa đơn đặt hàng hoặc khách hàng hoặc các bộ phận của chúng. Vì vậy, bạn có các Chế độ xem đó cho một mục đích và chế độ xem cụ thể và do đó nhiều lần trong các biến thể khác nhau.

Giả sử, bạn có OrderEditView và chế độ xem này sẽ cho phép chỉnh sửa thông tin đơn hàng và hiển thị khách hàng của đơn đặt hàng đó. Bạn sẽ có một OrderEditViewModel như thế này:

public class OrderEditViewModel 
{ 
    public int OrderId { get; set; } 

    public DateTime? ShippingDate { get; set; } 

    [StringLength(500)] 
    public string Remark { get; set; } 
    //... 

    public OrderEditCustomerViewModel Customer { get; set; } 
} 

public class OrderEditCustomerViewModel 
{ 
    [ReadOnly(true)] 
    public string Name { get; set; } 

    [ReadOnly(true)] 
    public string City { get; set; } 
    // ... 
} 

OrderEditCustomerViewModel này không cần một tham chiếu đến OrderEditViewModel.

Bạn có thể cư ViewModel này như sau:

var orderEditViewModel = context.Orders 
    .Where(o => o.OrderId == 5) 
    .Select(o => new OrderEditViewModel 
    { 
     OrderId = o.OrderId, 
     ShippingDate = o.ShippingDate, 
     Remark = o.Remark, 
     Customer = new OrderEditCustomerViewModel 
     { 
      Name = o.Customer.Name, 
      City = o.Customer.City 
     } 
    }) 
    .SingleOrDefault(); 

Mặt khác, nếu bạn có một CustomerEditView cho phép chỉnh sửa thông tin khách hàng và hiển thị các đơn đặt hàng của khách hàng trong một danh sách, ViewModel có thể là:

public class CustomerEditViewModel 
{ 
    public int CustomerId { get; set; } 

    [Required, StringLength(50)] 
    public string Name { get; set; } 

    [Required, StringLength(50)] 
    public string City { get; set; } 
    //... 

    public IEnumerable<CustomerEditOrderViewModel> Orders { get; set; } 
} 

public class CustomerEditOrderViewModel 
{ 
    [ReadOnly(true)] 
    public DateTime? ShippingDate { get; set; } 

    [ReadOnly(true)] 
    public string Remark { get; set; } 
    // ... 
} 

đây CustomerEditOrderViewModel không cần một tham chiếu đến CustomerEditViewModel và bạn có thể tạo các ViewModel từ cơ sở dữ liệu theo cách này ví dụ:

var customerEditViewModel = context.Customers 
    .Where(c => c.CustomerId == 8) 
    .Select(c => new CustomerEditViewModel 
    { 
     CustomerId = c.CustomerId, 
     Name = c.Name, 
     City = c.City, 
     Orders = c.Orders.Select(o => new CustomerEditOrderViewModel 
     { 
      ShippingDate = o.ShippingDate, 
      Remark = o.Remark 
     }) 
    }) 
    .SingleOrDefault(); 

Customer(*)ViewModel s và Order(*)ViewModel s khác nhau - liên quan đến tham chiếu cần thiết, thuộc tính và chú thích dữ liệu, tùy thuộc vào chế độ xem chúng được sử dụng.

Với những cân nhắc này, hãy nhớ rằng các tham chiếu chính xác lẫn nhau giữa OrderViewModelCustomerViewModel biến mất vì bạn thường không cần tham chiếu hai chiều cho lượt xem của mình.

+0

Slauma .. Làm thế nào để bạn thực hiện ánh xạ giữa viewmodel với thực thể EF và ngược lại? – user384080

+0

cũng .. làm thế nào để bạn cư trú công cộng IEnumerable Orders {get; bộ; } trong CustomerEditViewModel? bạn có lười biếng hay háo hức không? – user384080

+0

@ user384080: Ánh xạ từ thực thể EF tới ViewModel là hai đoạn mã với 'Select' (được gọi là" chiếu "và không lười biếng và không tải, nhưng gần với tải mong muốn hơn là bạn chỉ lấy các cột từ DB thực sự cần thiết cho ViewModel, không phải là thực thể đầy đủ sẽ là chi phí không cần thiết). Đặc biệt, đoạn cuối cùng cũng điền vào bộ sưu tập 'Orders' (xem bên trong' Chọn'). Để trở về từ ViewModel đến thực thể tôi sử dụng DTO, bạn có thể tự ánh xạ các thuộc tính từ ViewModel sang DTO hoặc sử dụng một công cụ như AutoMapper. – Slauma