如何使用Automapper将导航属性的视图模型进行映射

4

我正在尝试使用Automapper返回导航属性ViewModel

模型:

public class Month

{
    public int Id { get; set; }
    public string MonthName { get; set; }
    public int YearId { get; set; }
    public Year Year { get; set; }
}

public class Year

{
    public int Id { get; set; }
    public string YearName { get; set; }
}

视图模型:
public class MonthViewModel

{
    public int Id { get; set; }
    public string MonthName { get; set; }
    Display(Name = "Financial Year")
    public int YearId { get; set; }
    public YearViewModel Year { get; set; }
}

public class YearViewModel

{
    public int Id { get; set; }
    Display(Name = "Financial Year Name")
    public string YearName { get; set; }
}

我目前有一个显示月份列表的ASP.NET MVC视图映射,我需要将年份作为一列包含进去。
public  IActionResult Index()
{
    var months =  _monthRepo.GetAll().Include(m=>m.Year);

    IEnumerable<MonthViewModel> monthsVms = MonthViewModel.MapToViewModel(months);

    return View(monthsVms);
}



public static IEnumerable<MonthViewModel> MapToViewModel(IEnumerable<Month> dm)
{
    Mapper.CreateMap<Month, MonthViewModel>();
    Mapper.CreateMap<Year, YearViewModel>();
    return Mapper.Map<IEnumerable<Month>, IEnumerable<MonthViewModel>>(dm);
}

//However in my view when I want to refer to the year name like below:


@foreach (var item in Model)
{

    @Html.EditorFor(modelItem => item.YearViewModel.YearName)

}

然而item.YearViewModelnull

问题:

  1. 我如何设置AutoMapper,将相关导航属性ViewModel的Model映射到其ViewModel,并将其包含为我的ViewModel的导航属性?

主类与其导航属性之间存在一对一关系。 例如,我想要显示一个月份列表,每个月份旁边都有“月份名称”和“年份名称”两列。(因为我只想使用ViewModels的数据注释)

我在这里找到了一个类似的问题,但是我无法使其正常工作。

 Mapper.CreateMap<Month, MonthViewModel>().ForMember(dest => dest.YearViewModel.YearName, opt => opt.MapFrom(src => src.Year.YearName));

 Mapper.CreateMap<Year, YearViewModel>();

 return Mapper.Map<IEnumerable<Month>, IEnumerable<MonthViewModel>>(dm);

但是我遇到了同样的问题,当我尝试时。
 Mapper.CreateMap<Year, YearViewModel>();
 AutoMapper.Mapper.CreateMap<Month, MonthViewModel>()
     .ForMember(a => a.YearViewModel.YearName, b => b.ResolveUsing(c => c.Year.YearName));

解决方案是将整个导航属性进行映射。
Mapper.CreateMap<Year, YearViewModel>();
AutoMapper.Mapper.CreateMap<Month, MonthViewModel>()
     .ForMember(a => a.YearViewModel, b => b.ResolveUsing(c => c.Year));

首先,不要在每个请求中构建配置文件,这太糟糕了:(。其次,在您的控制器中添加一个名为get sources的方法。给定实体,将返回对象[],其中包含您希望映射到VM的每个项目,例如object[] {entity, monthNames,等}。循环这些并逐个映射到vm。 - Mark
有一个错别字,已经更正。Year到YearViewModel是1对1的关系。字段可以直接映射到彼此。ViewModel具有显示注释,数据模型具有Entity Framework数据注释。 - dfmetro
1个回答

3
也许这正是您想要的 -
AutoMapper.Mapper.CreateMap<Year, YearViewModel>();
AutoMapper.Mapper.CreateMap<Month, MonthViewModel>()
            .ForMember(a => a.Year, b => b.ResolveUsing(c => c.Year));
var o = AutoMapper.Mapper.Map<MonthViewModel>(new Month
            {
                Id = 1,
                MonthName = "January",
                YearId = DateTime.Now.Year,
                Year = new Year
                {
                    Id = DateTime.Now.Year,
                    YearName = DateTime.Now.Year.ToString()
                }
            }); // should map year as well.

"C dot" 智能感知未显示任何属性。 - dfmetro
啊!那是VS2013吗?你能再试一次吗? - Amit Kumar Ghosh
这是VS 2015更新1和“AutoMapper”:“4.1.1”。 - dfmetro
关闭解决方案,再重新打开。但语法就是这样。 - Amit Kumar Ghosh
我更新了我的原始问题。关于什么不起作用。 - dfmetro
你需要映射整个 YearViewModel,而不是它的属性。 - Amit Kumar Ghosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接