Je crée ma première application MVC dans Visual Studio 2013 (MVC 5) et je ne suis pas certain de la meilleure façon de configurer mon modèle.
J'ai généré un modèle de structure d'entité à l'aide de code-first à partir d'une base de données existante. Mon premier réflexe a été de créer des classes intermédiaires qui seraient le modèle utilisé par les vues et de faire travailler ces classes avec les classes framework d'entité.
Pendant que j'écrivais les classes intermédiaires, j'ai réalisé que je ré-implémentais principalement beaucoup de choses que les classes EF faisaient déjà juste avec le setter privé occasionnel ou cast d'un type de données à un autre. Cela semblait donc être un gaspillage.
La règle générale est-elle d'utiliser directement les classes de structure d'entité comme modèle pour une application MVC? Ou y a-t-il un avantage qui me manque pour la construction de ces classes intermédiaires?
Dans mes applications, j'ai toujours séparé les choses, avec différents modèles pour la base de données (Entity Framework) et MVC. Je les ai également séparés en différents projets:
Au lieu de contenir des références à d'autres objets comme le font les entités de domaine, les modèles MVC contiennent des ID sous forme d'entiers.
Lorsqu'une demande GET pour une page arrive, le contrôleur MVC exécute la requête de base de données, qui renvoie une entité. J'ai écrit des méthodes "Converter" qui prennent une entité de domaine et la convertissent en un modèle MVC. Il existe d'autres méthodes qui font le contraire (d'un modèle MVC à une entité de domaine). Le modèle est ensuite transmis à la vue, et donc au client.
Lorsqu'une demande POST arrive, le contrôleur MVC obtient un modèle MVC. Une méthode de conversion le convertit en une entité de domaine. Cette méthode effectue également toutes les validations qui ne peuvent pas être exprimées en tant qu'attributs, et s'assure que si l'entité de domaine existe déjà, nous la mettons à jour plutôt que d'en obtenir une nouvelle. Les méthodes ressemblent généralement à ceci:
public class PersonConverter
{
public MyDatabaseContext _db;
public PersonEntity Convert(PersonModel source)
{
PersonEntity destination = _db.People.Find(source.ID);
if(destination == null)
destination = new PersonEntity();
destination.Name = source.Name;
destination.Organisation = _db.Organisations.Find(source.OrganisationID);
//etc
return destination;
}
public PersonModel Convert(PersonEntity source)
{
PersonModel destination = new PersonModel()
{
Name = source.Name,
OrganisationID = source.Organisation.ID,
//etc
};
return destination;
}
}
En utilisant ces méthodes, je supprime la duplication qui se produirait autrement dans chaque contrôleur. L'utilisation de génériques peut dédupliquer encore plus les choses.
Faire les choses de cette façon présente de multiples avantages:
Je dirais que cela dépend vraiment de votre application. S'agit-il simplement de CRUD pur, sans aucune logique métier? Ensuite, j'utilisais les modèles EF directement dans mes vues.
La plupart du temps, au moins une logique métier est impliquée, puis une couche entre les modèles de données/EF et la vue peut être une bonne idée. Dans ce cas, il peut être approprié de faire "CQRS-lite" (voir ci-dessous) et d'utiliser différents modèles pour entrer et sortir de votre contrôleur. La plupart du temps, les modèles de lecture sont beaucoup plus "gras" que les modèles d'écriture ...
Cependant, si l'application contient beaucoup de logique métier et/ou doit évoluer beaucoup, j'implémenterais au moins le cœur de celui-ci en utilisant CQRS (Command Query Responsibility Segregation), DDD (Domain Driven Design) et éventuellement Event Sourcing. Ensuite, EF pourrait être utilisé comme façade du modèle de lecture.
Rappelez-vous également que vous n'avez pas besoin de vous en tenir à une stratégie/modèle pour l'ensemble de l'application, certains domaines peuvent être du CRUD pur et d'autres peuvent contenir beaucoup de logique métier ...