2012-06-26 43 views
2

我开始使用映射域模型来查看ASP.NET MVC中的模型,然后观看建议以将特定视图模型传递给视图。MVC如何从我的域模型映射到特定的视图模型

我已经能够管理一个域模型的基本映射到一个更简单的视图模型,但是现在需要生成一个更复杂的视图模型并且不能算出来。我有以下的域模型

public class Club 
{ 
    public int ClubID { get; set; } 
    public string FullName { get; set; } 
    public string Description { get; set; } 
    public string Telephone { get; set; } 
    public string URL { get; set; } 
    public DateTime CreatedDate { get; set; } 

    public virtual ICollection<Member> Members{ get; set; } 
} 

public class Member 
{ 
    public int MemberID{ get; set; } 
    public string Name { get; set; } 
    public MemberType Membership{ get; set; } 
    public virtual Club Club { get; set; } 
    public virtual int ClubID { get; set; } 
} 

public enum MemberType 
{ 
    Standard, 
    Special, 
    Limited 
} 

我想要映射到一个视图模型,如下所示(注:我是这样划分的,因为我觉得很有道理,但我不知道)...

public class ClubDetailsViewModel 
{ 
    public int ClubID { get; set; } 
    public string FullName { get; set; } 
    public string Description { get; set; } 
    public IList<ClubDetailsMemberSummaryViewModel> Members { get; set; } 
} 

public class ClubDetailsMemberSummaryViewModel 
{ 
    public MemberType Membership { get; set; } 
    public int MemberCount { get; set; } 
} 

我试图用落得是显示一些俱乐部的细节加上在俱乐部与会员的计数的成员类型的总结报告的页面。如:

Some Club Name 
Description of the club..... 

CLUB MEMBERS 
Limited - 15 
Standard - 100 

所以我认为视图模型是有道理的,这(虽然可能是一个更好的方式来做到这一点)。我在哪里挣扎是如何映射元素。我可以让俱乐部将主要字段映射到俱乐部视图模型,但是真的无法解决如何将俱乐部列表的结果映射到其视图模型,然后将其作为列表添加到主视图模型。

我是从我的仓库使用此

var clubs = _clubRepository.GetClubByID(ID); 

然后我就可以改变其使用返回了实体框架数据访问层中包括使用该

var grpCourts = from c in clubs.Members 
       group c by c.Membership into grp 
       select new { st = grp.Key, count = grp.Distinct().Count() }; 
法院得到俱乐部

我将如何遍历结果记录并将其映射到ClubDetailsMemberSummaryViewModel,然后将这些列表添加到主ClubDetailsViewModel?

回答

1

你映射从ClubClubDetailsViewModel将琐碎的Members除了更具体的细节。对于那个属性,你可以写一个快速解析器内联或编写你自己的自定义解析器。内联解析器会是这个样子:

Mapper.CreateMap<Club, ClubDetailsViewModel>() 
    .ForMember(dest => dest.Members, opt => opt.ResolveUsing(src => 
    { 
     return src.Members 
      .GroupBy(m => m.Membership) 
      .Select(grp => new ClubDetailsMemberSummaryViewModel 
      { 
       Membership = grp.Key, 
       MemberCount = grp.Distinct().Count() 
      }); 
    })); 

我认为这是很好的做法,重构这样更复杂的解析器了自己的类:

public class MembershipClubDetailsResolver : ValueResolver<Club, IList<ClubDetailsMemberSummaryViewModel>> 
{ 
    protected override IList<ClubDetailsMemberSummaryViewModel> ResolveCore (Club source) 
    { 
     return source.Members 
      .GroupBy (m => m.Membership) 
      .Select(grp => new ClubDetailsMemberSummaryViewModel 
      { 
       Membership = grp.Key, 
       MemberCount = grp.Distinct().Count() 
      }) 
      .ToList(); 
    } 
} 

,然后使用该解析器在您的映射:

Mapper.CreateMap<Club, ClubDetailsViewModel>() 
    .ForMember(dest => dest.Members, opt => opt.ResolveUsing<MembershipClubDetailsResolver>()); 
+0

谢谢。这工作完美,我想我明白它是如何工作的。你会说有pro/cons使用这种映射方式吗? 我的其他查询将是如果我有一个不相关的对象列表(我们称之为Foo),我需要包含在视图,因此在视图模型。例如,我有一个地址列表(但没有以任何方式链接到俱乐部或会员),我还需要在侧边栏中显示。因为这些必须由另一个查询返回,如果他们有自己的局部视图,并因此拥有自己的视图模型,或者有办法将它们包含到主视图模型中? – stevejgordon

+0

在问题1中,你是指什么类型的映射(答案中的第一个或第二个)?至于问题2,您可以将“Addresses”属性添加到您的ViewModel并将其填充到AutoMapper之外。您仍然可以以这种方式分离视图和查看模型。很高兴它对你有效! –

0

你的映射似乎是相当复杂的,我想我会用automapper的.ConvertUsing方法

Mapper.CreateMap<List<Club>,List<ClubDetailsViewModel>>() 
.ConvertUsing<ClubToClubDetailsViewModel>(); 

转换类具有以下继承

public class ClubToClubDetailsViewModel: TypeConverter<List<Club>,List<ClubDetailsViewModel>> 
{ 
.... 
} 

或者你可以创建鼓捣两个“简单”映射

Mapper.CreateMap<Club,ClubDetailsViewModel>() 

这将映射前夕除了名为Members的属性

然后,您需要为ClubDetailsMemberSummaryViewModel创建成员映射,您可以手动执行映射,或者您也可以在automapper中配置此功能。

有关automapper您可以访问https://github.com/AutoMapper/AutoMapper/wiki

相关问题