2016-01-15 2 views
2

Я все еще участвую в MVC, и мне недавно предложили взглянуть на использование AutoMapper для отображения моего ViewModel. Итак, я начал тест, но я не понимаю, как сопоставить два объекта, и я не могу найти пример.Не удалось добавить второй объект в ViewModel с Automapper?

У меня есть таблица Person и таблица адресов. Я хочу объединить их в ViewModel, чтобы перейти к моему представлению. Глядя на примеры, они всегда показывают, как сопоставить одну сущность, но не две.

В следующем коде я вижу, что оба объекта currentPerson и currentAddress заполняются данными с помощью отладчика, но тогда моя текущая модель ViewModel имеет только данные Person. Это имеет смысл, потому что я использую Mapper.Map для Person, но как я могу сообщить текущему члену о карте адреса?

public ActionResult Edit(int id = 0) 
     { 
      using (DataContext db = new DataContext()) 
      { 
       Person currentPerson = db.Person.Find(id); 
       Address currentAddress = db.Address.Single(a => a.PID == id); 

       AutoMapper.Mapper.CreateMap<Person, AdminViewModel>(); 
       AutoMapper.Mapper.CreateMap<Address, AdminViewModel>(); 

       MemberViewModel currentMember = AutoMapper.Mapper.Map<AdminViewModel>(currentPerson); 

       return View(currentMember); 
      } 
     } 
+0

Как насчет того, как вы создаете два свойства в 'AdminViewModel', а затем сопоставляете их по отдельности? –

+0

Это то, что я делал изначально, и именно тогда мне предложили использовать Automapper, чтобы не было необходимости вручную отображать свойства. – Caverman

+0

да и, честно говоря, я так делаю все время. Когда вы их сопоставляете отдельно, назначьте их вручную, чтобы просмотреть модель –

ответ

3

AutoMapper.Map имеет перегрузку с исходным и целевым объектом. Таким образом, вы можете воспользоваться ею, используя что-то вроде этого:

Создать ViewModels

public class PersonViewModel 
{ 
    //your person fields here.. 
    //create them with the same name as Person 
    //to avoid having to set each field during mapping 
} 

public class AddressViewModel 
{ 
    //your address fields here.. 
} 

public class AdminViewModel 
{ 
    public PersonViewModel Person {get; set;} 

    public AddressViewModel Address {get; set;} 
} 

Крит Отображения (Вы должны централизовать все отображения в классе):

public class EntityToViewModelProfile : Profile 
{ 
    protected override void Configure() 
    { 
     //Create mappings for Person and Address 
     AutoMapper.Mapper.CreateMap<Person, AdminViewModel>(); 
     AutoMapper.Mapper.CreateMap<Address, AdminViewModel>(); 


     //Create a map to AdminViewModel for both Person and Address 

     Mapper.CreateMap<Models.Person, Models.AdminViewModel>() 
      .ForMember(dest => dest.Person, opt => opt.MapFrom(src => src)); 

     Mapper.CreateMap<Models.Address, Models.AdminViewModel>() 
      .ForMember(dest => dest.Address, opt => opt.MapFrom(src => src)); 
    } 
} 

Регистрация EntityToViewModelProfile в Global.asax.cs

AutoMapper.Mapper.Initialize(x => 
{ 
    x.AddProfile<EntityToViewModelProfile>(); 
}); 

Затем в контроллере использовать перегрузку .Map

using (DataContext db = new DataContext()) 
{ 
    Person currentPerson = db.Person.Find(id); 
    Address currentAddress = db.Address.Single(a => a.PID == id); 

    var mapPerson = AutoMapper.Mapper.Map<Person, AdminViewModel>(currentPerson); 

    var mapPersonAndAddress = AutoMapper.Mapper.Map<Address, AdminViewModel>(currentAddress, mapPerson); 

    return View(mapPersonAndAddress); 
} 
+0

что такое 'destination2'? –

+0

@jpgrassi, в разделе «Создать сопоставления», для чего используется. FORMember?Из примеров, которые я видел, было похоже, что вы используете ForMember для назначения двух значений параметру (например: DisplayName = FristName + LastName). Если я сопоставляю свойства один к одному, мне все равно нужен .ForMember? – Caverman

+0

@ Каверман, да, вы правы. У меня такой же вопрос. Вам, вероятно, просто нужно создать два простых сопоставления для человека и другого для адреса, но я не тестировал это. Я просто оставлю это, чтобы вы могли ясно понять, что происходит. – jpgrassi

0

Ответ от Jpgrassi выглядит хорошо, и это очень хороший способ, чтобы преобразовать. Но если вы делаете преобразования в слое DB или BL (а не в самом контроллере), сохранение ваших конверсий в Business Objects в BOViewModel (Person to PersonViewModel и т. Д.) В a более многократно используется. Чаще всего вам нужен отдельный проект, который определяет ваши BOViewModels (что-то вроде MyProject.BO)

Я предпочел бы следовать простой и прямой подход, чтобы создать AdminViewModel,

var personViewModel = AutoMapper.Mapper.CreateMap<Person, PersonViewModel>(); 
var addressViewModel = AutoMapper.Mapper.CreateMap<Address, AddressViewModel>(); 

Эти преобразования полезны для преобразования БД объекты к BO, что в идеале имеет место в слое DB или BL. Затем передайте personViewModel и addressViewModel в контроллер и создайте AdminViewModel в контроллере.

Это прост, и этот шаблон работает через границы обслуживания или приложения со многими слоями.

+0

На данный момент я просто хочу сделать это в контроллере, но у меня есть намерения вернуться и реорганизовать код еще раз, когда я получу свою голову, обернутую вокруг всего этого немного больше. Я хотел бы иметь центральное расположение, такое как бизнес-уровень, который будет делать все это для меня, потому что я могу видеть, где мне нужно создать MemberViewModel в нескольких местах. Такие вещи, как отображение участника, раздела MyAccount и раздела администратора для их редактирования. Я бы предпочел сохранить этот код в одном месте и не делать то же самое в нескольких контроллерах. – Caverman

+0

Звучит неплохо! попытайтесь использовать его как можно больше. Если вы сохраните компоненты просто, это произойдет автоматически. – Dhanuka777

Смежные вопросы