2010-02-15 19 views
2

J'essaie de nettoyer mes méthodes d'action dans un projet ASP.NET MVC en utilisant des modèles de vue. Actuellement, mes modèles de vue contiennent des entités qui pourraient avoir des relations avec d'autres entités. Par exemple, la classe ContactViewModel peut avoir un contact, qui peut avoir une adresse, les deux étant des entités distinctes. Pour rechercher une liste d'objets Contact, je pourrais faire quelque chose comme ceci.ASP. NET MVC: Mappage d'entités pour afficher le modèle

IList<Contact> contacts; 

using (IContactRepository repository = new ContactRepository()) 
{ 
    contacts = repository.Fetch().ToList(); 
} 

EditContactViewModel vm = new EditContactViewModel(contacts); 

return View(vm);

Cette méthode pose quelques problèmes. Par exemple, le référentiel est interrogé dans une instruction using. Au moment où la vue s'affiche, le contexte est hors de portée, ce qui empêche la vue d'interroger l'adresse associée au contact. Je pourrais permettre un chargement passionné, mais je préférerais ne pas le faire. En outre, je n'aime pas que le modèle d'entité ait saigné à mon sens (je pense que c'est une mauvaise idée pour mon View d'avoir connaissance de la relation entre Contact et Adresse, mais n'hésitez pas à ne pas être d'accord avec moi).

J'ai envisagé de créer une classe grossie contenant des propriétés des entités Contact et Adresse. Je pourrais alors projeter les entités Contact et Adresse dans mon nouvel objet aplati. Une de mes préoccupations avec cette approche est que mes méthodes d'action peuvent être un peu occupé et je ne sais pas pense AutoMapper est capable de mapper deux ou plusieurs objets dans un seul type.

Quelle technique est/est préférée pour surmonter mes préoccupations?

Répondre

3

Automapper fonctionnera pour votre cas. Ce que vous avez est un graphique d'objet, une chose a plus de choses, que Automapper gère très bien.

+0

Très cool. Je suis encore nouveau sur AutoMapper, donc je ne savais même pas qu'il pouvait cartographier, comme ça. Merci beaucoup. – senfo

1

Compte tenu de ces préoccupations pour ...

D'abord, si vous êtes inquiet au sujet de la déclaration et l'utilisation du dépôt (je ne sais pas s'il est LINQ to SQL ou LINQ-to-entités, mais ce n'est pas grave), ce que je vous recommande de faire est d'implémenter IDisposable sur votre contrôleur, puis de stocker le référentiel dans un champ sur le modèle ou dans le contrôleur ou quelque part où vous avez accès à la vue (si vous en avez besoin, si le modèle en a connaissance alors que l'objet est "vivant", alors vous avez juste besoin de le garder pour la vie du contrôleur). Puis, lorsque la requête est terminée, la méthode Dispose sur votre contrôleur est appelée et vous pouvez y disposer du référentiel.

Personnellement, j'ai une méthode sur ma classe de contrôleur de base qui ressemble à ceci:

protected T AddDisposable<T>(T disposable) where T : class, IDisposable 
{ 
    // Error checking. 
    if (disposable == null) throw new ArgumentNullException("disposable"); 

    // Add to list 
    ... 
} 

Fondamentalement, il vous permet de stocker les mises en œuvre IDisposable, puis dans la mise en œuvre IDisposable du contrôleur, il parcourt la liste, disposer de tout.

En ce qui concerne l'exposition de l'adresse sur le modèle d'entité, je ne vois pas cela comme un problème de saignement, personnellement. L'adresse fait partie de la composition du contact (IMO), donc il serait faux de pas de l'avoir là.

Cependant, je ne suis pas en désaccord si vous ne voulez pas là parce que vous voulez vous concentrer sur un type dans un contrôleur à la fois, etc., etc.

À cette fin, vous voulez créer des objets de transfert de données qui, fondamentalement, correspondent au type que vous exposez dans le modèle de vue et à votre modèle d'entité.