2012-06-26 2 views
2

Je commence avec le concept de mappage des modèles de domaine pour afficher les modèles dans ASP.NET MVC après avoir vu une recommandation pour cela afin de transmettre des viewModels spécifiques aux vues .MVC Comment mapper de mon modèle de domaine à un modèle de vue spécifique

J'ai été capable de gérer un mappage de base d'un modèle de domaine vers un modèle plus simple avec moins de propriétés, mais j'ai maintenant besoin de produire un modèle plus complexe et je ne peux pas le comprendre. Je les modèles de domaine suivants

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 
} 

Je veux la carte à un modèle de vue comme celui-ci (note: J'ai divisé comme ça parce que je pense qu'il est logique mais je ne suis pas sûr) ...

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

Ce que je suis en train de retrouver avec une page qui affiche certains détails du club ainsi qu'un rapport de synthèse des types de membres au club avec un compte des membres. Tels que:

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

CLUB MEMBERS 
Limited - 15 
Standard - 100 

Je pense donc que le viewmodel est logique pour cela (bien que peut-être une meilleure façon de le faire). Là où je me bats, c'est comment cartographier les éléments. Je peux demander au club de mapper les champs principaux au club viewmodel, mais je ne peux vraiment pas déterminer comment mapper le résultat de la liste des clubs sur leur modèle de vue, puis l'ajouter au modèle de vue principal sous forme de liste.

Je reçois les clubs de mon dépôt en utilisant ce

var clubs = _clubRepository.GetClubByID(ID); 

Ensuite, je peux transformer les tribunaux qui sont retournés à l'aide d'une inclure dans la couche d'accès aux données du cadre de l'entité utilisant ce

var grpCourts = from c in clubs.Members 
       group c by c.Membership into grp 
       select new { st = grp.Key, count = grp.Distinct().Count() }; 

Comment naviguer dans les enregistrements résultants et les mapper à ClubDetailsMemberSummaryViewModel, puis ajouter la liste de ceux-ci au ClubDetailsViewModel principal?

Répondre

1

Votre carte Club-ClubDetailsViewModel sera trivial à l'exception de Members. Pour cette propriété, vous pouvez écrire un résolveur rapide en ligne ou écrire votre propre résolveur personnalisé.Un résolveur en ligne ressemblerait à quelque chose comme ceci:

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

Je pense qu'il est bon de factoriser résolveurs plus complexes comme celui-ci à leurs propres classes:

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

Et ensuite utiliser ce résolveur dans votre application:

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

Merci. Cela a fonctionné parfaitement et je pense que je comprends comment cela fonctionne. Diriez-vous qu'il y avait des avantages/inconvénients à utiliser cette méthode de cartographie? Mon autre requête serait si j'ai une liste d'objets sans rapport (appelons-les Foo) que j'ai besoin d'inclure dans la vue et donc dans le viewmodel. Par exemple, j'ai une liste d'adresses (mais pas liées aux clubs ou aux membres) que je dois aussi afficher dans une barre latérale. Comme ceux-ci devront être retournés par une autre requête s'ils ont leur propre vue partielle et donc possèdent un viewmodel ou y a-t-il un moyen de les inclure dans le viewmodel principal? – stevejgordon

+0

À la question 1, quel type de cartographie voulez-vous dire (le premier ou le deuxième dans la réponse)? Comme pour la question 2, vous pouvez ajouter une propriété 'Addresses' à votre ViewModel et le remplir en dehors d'AutoMapper. Vous pouvez toujours avoir des vues séparées et voir des modèles de cette façon. Content que ça a marché pour vous! –

0

Votre cartographie semble être assez complexe, je pense que je voudrais utiliser la méthode .ConvertUsing de automapper

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

La classe de conversion a l'héritage suivant

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

Sinon, vous pouvez bricoler avec la création deux mappings "simples"

Mapper.CreateMap<Club,ClubDetailsViewModel>() 

rything excepté la propriété appelée Membres

Ensuite, vous devez créer un mappage pour les membres de ClubDetailsMemberSummaryViewModel, vous pouvez effectuer ce mappage manuellement ou vous pouvez le configurer dans automapper également.

Pour plus de détails plus spécifiques sur automapper vous pouvez visiter https://github.com/AutoMapper/AutoMapper/wiki

Questions connexes