无法使用Automapper将第二个实体添加到ViewModel?

时间:2016-01-15 03:47:03

标签: c# asp.net-mvc entity-framework

我还在学习MVC,我最近刚建议使用AutoMapper来映射我的ViewModel。所以,我开始测试,但我不了解如何映射两个实体,也不能找到一个例子。

我拥有的是Person表和Address表。我想将两者合并为一个ViewModel传递给我的View。看一些例子,他们总是展示如何映射一个实体而不是两个实体。

在下面的代码中,我可以看到我的currentPerson和currentAddress对象都使用调试器填充了数据,但是我的currentMember ViewModel只有Person数据。这是有道理的,因为我只在Person上使用Mapper.Map但是如何告诉currentMember也映射地址呢?

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);
            }
        }

2 个答案:

答案 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));
    }
}

Global.asax.cs

中注册EntityToViewModelProfile
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);
}

答案 1 :(得分:0)

来自Jpgrassi的回答看起来不错,而且这是很酷的转换方式。但是如果您正在DB或BL层(而不是Controller本身)中进行转换,那么在a中保持对Business Objects到BOViewModel(Person to PersonViewModel等)的转换更加可重用。更常见的是,你需要一个单独的项目来定义你的BOViewModels(像MyProject.BO这样的东西)

我宁愿按照简单直接的方法来创建AdminViewModel,

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

这些转换对于将DB对象转换为BO非常有用,理想情况下,这些转换将在DB或BL层中进行。然后将personViewModel和addressViewModel传递给Controller,并在控制器中创建AdminViewModel。

这很简单,这种模式适用于服务边界或具有多个层的应用程序。