2

在观看了将特定视图模型传递给视图的建议之后,我开始使用将域模型映射到 ASP.NET 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?

4

2 回答 2

1

Club您从to的映射ClubDetailsViewModel将是微不足道的,除了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>());
于 2012-06-26T13:24:41.827 回答
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

于 2012-06-26T12:34:24.363 回答