2012-04-20 18 views
7

Tôi hiện đang sử dụng ViewModels để tách các Chế độ xem của tôi khỏi cấu trúc Mô hình thực tế."Hợp nhất" Mô hình và ViewModel có hoặc không có AutoMapper?

Ví dụ: Tôi có một thực thể kiên trì người dùng và một ViewModel MyProfile chứa tất cả thông tin mà người dùng có thể tự thay đổi. Để chuyển đổi từ Người dùng sang MyProfile Tôi đang sử dụng Automapper.

Bây giờ sau khi người dùng đăng lại thông tin (đã thay đổi) của anh ấy, tôi cần lưu các thông tin này. Nhưng thông tin trong ViewModel không hoàn chỉnh và khi AutoMapper tạo một thực thể persistence User từ ViewModel, thông tin quan trọng sẽ bị mất.

Tôi không muốn hiển thị thông tin này cho Lớp Chế độ xem, đặc biệt là không có các phần tử biểu mẫu ẩn.

Vì vậy, tôi cần một cách để hợp nhất một ViewModel thành một thực thể kiên trì. Tôi có thể làm điều đó với AutoMapper, hay tôi phải làm điều đó bằng tay?

Ví dụ:

Lớp người dùng của tôi chứa ID, FirstName, LastName, Username và Password. Người dùng chỉ nên chỉnh sửa Tên và Họ của mình trong tiểu sử của mình. Do đó ProfileViewModel của tôi chứa ID, Firstname và LastName. Sau khi gửi lại thông tin từ biểu mẫu, Automapper tạo một đối tượng User từ ProfileViewModel đã chuyển, và trong đối tượng này chỉ có ID, Firstname và LastName được thiết lập. Khi cung cấp Thực thể này cho Kho lưu trữ của tôi, tôi đã mất thông tin về tên người dùng và mật khẩu.

+0

Tại sao các thông tin không được hoàn thành? Bạn có thể đăng một đoạn mã không? –

+0

Tôi đã sử dụng Mapper.Map (mô hình) thay vì đầu tiên tra cứu Thực thể người dùng và sau đó sử dụng Mapper.Map (người dùng, kiểu máy) – ckonig

Trả lời

12

Vì vậy, tôi cần một cách để hợp nhất ViewModel thành thực thể kiên trì. Tôi có thể làm điều đó với AutoMapper hay tôi phải thực hiện thủ công?

Có, bạn có thể thực hiện điều đó bằng tính năng Tự động lập bản đồ. Ví dụ:

public class Model 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class ViewModel 
{ 
    public string Name { get; set; } 
} 

class Program 
{ 
    static void Main() 
    { 
     // define a map (ideally once per appdomain => usually goes in Application_Start) 
     Mapper.CreateMap<ViewModel, Model>(); 

     // fetch an entity from a db or something 
     var model = new Model 
     { 
      Id = 5, 
      Name = "foo" 
     }; 

     // we get that from the view. It contains only a subset of the 
     // entity properties 
     var viewModel = new ViewModel 
     { 
      Name = "bar" 
     }; 

     // Now we merge the view model properties into the model 
     Mapper.Map(viewModel, model); 

     // at this stage the model.Id stays unchanged because 
     // there's no Id property in the view model 
     Console.WriteLine(model.Id); 

     // and the name has been overwritten 
     Console.WriteLine(model.Name); 
    } 
} 

in:

5 
bar 

Và dịch này thành một mô hình ASP.NET MVC tiêu biểu:

[HttpPost] 
public ActionResult Update(MyViewModel viewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     // validation failed => redisplay view 
     return View(viewModel); 
    } 

    // fetch the domain entity that we want to udpate 
    DomainModel model = _repository.Get(viewModel.Id); 

    // now merge the properties 
    Mapper.Map(viewModel, model); 

    // update the domain model 
    _repository.Update(mdoel); 

    return RedirectToAction("Success"); 
} 
+0

Được rồi, điều đó có ý nghĩa ngay bây giờ! Và có vẻ tốt hơn nhiều so với sử dụng phương thức UpdateModel(). – ckonig

Các vấn đề liên quan