Archive

Articles taggués ‘Entity Framework’

Entity Framework Model First

J’ai eu l’occasion d’intervenir sur un projet utilisant Entity Framework 4.1 avec une approche Model First. Je profite de ce billet pour faire part de mes premiers retours.

Contexte technique du projet

  • une trentaine d’entités, dont une dizaine stéréotypées référentiel
  • des règles métier
  • un workflow de validation
  • une approche domain driven

Rappels sur les principes de l’approche Model First

Je ne vais pas détailler ces rappels car il existe de nombreux articles sur le sujet. Je vous propose celui-ci qui me parait intéressant.

Dans les grandes lignes, le processus de développement consiste en deux étapes :

  1. définition d’un modèle du domaine, appelé modèle conceptuel dans Entity Framework. Cette définition est généralement réalisée à partir d’un designer graphique, outil permettant de créer visuellement un pseudo diagramme de classes. Pour les plus courageux (ou quand l’outil a atteint ses limites), il est également possible de modifier le fichier XML sous-jacent. Mais soyons clairs : le fichier de mapping XML de NHibernate est peu complexe par rapport au fichier EDMX proposé par EF !
  2. transformations de modèles. A partir du modèle conceptuel, EF nous propose des outils permettant de générer les modèles relationnels et objets ainsi qu’une partie de la couche d’accès aux données. Ces transformations reposent sur les T4 Text Templates, outil simple et efficace de génération de code.

Quelques principes adoptés sur le projet

  • Domain driven : un modèle du domaine riche, contraint, contenant notamment les règles métier.
  • L’IHM, réalisée avec ASP.NET Web forms et jQuery n’a alors en théorie plus qu’à venir se greffer sur le modèle
  • patterns context-per-request et conversation utilisée dans seam
  • utilisation partielle du scaffolding pour les entités de référence

Avantages

  • Outillage productif intégré dans Visual Studio
  • Adaptation de la génération avec les T4Templates. Voici un exemple d’adaptation : partant du principe qu’une contrainte sur le domaine apporte de la richesse et évite des erreurs d’incohérence, j’insiste sur le fait de marquer les contraintes. Si une entité Livre a nécessairement un titre, le constructeur de Livre devrait avoir un paramètre non optionnel « titre » et la visibilité du setter de la propriété « Titre » devrait être réduite. Quelques lignes dans le T4Template et cette règle est généralisée à l’ensemble du domaine !

    Relation ManyToOne requise

    Relation ManyToOne requise

  • Refactor facilité : Approche agile, permettant de refactorer pour améliorer la sémantique du domaine et donc sa compréhension. Le travail à réaliser est opéré sur le modèle conceptuel. Domaine, repository, schéma de BD sont générés : ça ne coute donc presque rien. Un peu de rework est parfois nécessaire dans les couches supérieures, en fonction du refactor apporté.

Limites rencontrées

  • Mécanisme de Facets non extensible. Les Facets permettent d’apporter des précisions sur les propriétés des entités : par exemple si la propriété est Nullable, sa longueur maximale… Certaines facets sont manquantes, typiquement la facet unique. Certes, les équipes de Microsoft travaille dessus, mais je doute qu’ils puissent couvrir tous les cas de figures. Ce qui je pense pourrait être intéressant, serait introduire un point d’extension permettant aux développeurs de définir de nouvelles Facets. Les développeurs pourraient alors exploiter ces Facets dans les templates.
  • Méta données des entités non extensibles. Certaines entités jouent des rôles particuliers, nécessitant une implémentation qui leur est propre. C’est par exemple le cas des entités de référence (les unité de mesure, les catégories de produits, …). Ces entités ont une particularité : les interfaces d’administration sont des interfaces de type CRUD. Le scaffolding est une bonne option pour ce type d’interface. Pour l’activer, il faut tagguer les classes C#. Je trouve dommage qu’on ne puisse pas tagguer ces entités directement dans le modèle avec une annotation custom. Dans l’exemple, l’annotation aurait été Referential. Dans la transformation de modèle, on aurait alors pu rajouter une règle : toutes les entités stéréotypées Referential supportent le scaffolding. A défaut, nous avons utiliser le mécanisme des classes partielles pour apporter cette information. 
  • Stratégie d’héritage globale : il existe plusieurs stratégies pour mapper un héritage objet dans un modèle relationnel (table par type, table par classe concrète, table par hiérarchie). Le choix d’une stratégie doit être traitée au cas par cas : dois-je privilégier la performance sur une requête polymorphe ? dois-je promouvoir le faible couplage ? Malheureusement dans l’outil, le choix est unique pour tout le modèle :(. La encore, un mécanisme d’extension de type stéréotype aurait été le bienvenu.
  • Namespace globale. Actuellement avec l’outil, on ne peut définir qu’un seul Namespace pour un modèle EDMX.

Ma conclusion

Je trouve cette approche productive pour des projets nécessitant peu de spécificités (comprendre sortir du cadre prévu par Microsoft) et dont la complexité du modèle du domaine reste raisonnable. Comme toutes les approches Model Driven, la modification des templates n’est intéressante que si le nombre d’entités est significatif . La limite majeure pour des projets plus conséquents, c’est le manque de points d’extension. Je terminerai par un dernier constat qui est également vrai pour les outils de ce type : ne pas se laisser berner par la facilité apparente !

Categories: .NET Tags: ,

Coding Dojo sur Entity Framework

Voici un rapide retour sur le coding dojo organisé le 16 juin 2011 à Objet Direct sur le thème « Entity framework code first ».

L’approche code first présentée ici a bien évolué avec la version 4.1, et notamment la partie convention over configuration qui permet de gagner en productivité et en clarté.

Pour changer du format classique des formations en soirée, nous sommes partis d’une base de coding dojo randori kata. Le programme était le suivant :

  • présentation générale d’entity framework
  • présentation du mode code first
  • mise en œuvre du coding dojo avec les règles suivantes
    • 1 machine, 1 projecteur
    • un nombre de participants inférieur à 7 personnes
    • un challenge
    • des périodes de 5 minutes, dans lesquelles un pilote et un copilote avancent sur le challenge
    • à la fin de la période, le copilote devient pilote et un autre participant devient le copilote
  • TDD

Difficultés rencontrées et constat :

  • 4, 5 personnes c’est vraiment bien
  • la période de 5 minutes n’est pas suffisante. 7 minutes c’est mieux

Les plus par rapport à un format plus classique :

  • dynamique et vivant
  • hétérogénéité des participants plus facile à gérer
  • moins de préparation
  • plus ouvert, très enrichissant : les participants peuvent introduire de nouvelles notions
  • dense, informations très condensées, rythme soutenu
  • favorise les échanges
  • objectifs plus facilement atteignables

Architecture d’une application Windows en .NET

On m’a récemment demandé un avis sur l’architecture d’une application Windows écrite en .NET. Bien que l’exercice soit toujours difficile car cela dépend bien évidemment du contexte, je profite de ce billet pour donner quelques pistes de réflexions quand au choix des briques logicielles. Le demandeur venant du monde Java, mon discours sera orienté dans ce sens.

  • Outil de mapping objet relationnel : à mon sens, il y a aujourd’hui 2 alternatives en .NET :
    1. NHibernate, le cousin germain de Hibernate. Pour éviter la configuration dans les fichiers XML, je conseille le mode fluent ainsi que l’API de requêtage  LINQ . Un début de présentation est disponible ici. Sinon, il y a aussi les slides de la formation en soirée qui a été animée l’automne passé.
    2. Entity Framework. La dernière version reprend des principes de NHibernate, dont notamment la programmation par POCO (Plain Old C# Object), le lazy loading (chargement tardif). Comme je le mentionnais dans ce billet, plusieurs modes sont disponibles : Database first, Model First et maintenant Code First, très proche de Fluent NHibernate. Un atelier en soirée aura lieu fin mai sur ce thème.
  • Spring.NET : je trouve la question délicate, car cela dépend vraiment du besoin (IoC, programmation par aspects, boîte à outils,  framework MVC …). Comme son cousin Java, c’est une véritable boîte à outils très (trop ?) riche. Cette richesse est parfois synonyme de complexité et de lourdeur, par rapport à d’autres conteneurs IoC tels que NInject, Autofac, StructureMap, Castle Windsor ou Unity. Son principal inconvénient était sa configuration « XML based ». Ce point devrait être adressé avec la sortie de CodeConfig. Sa proximité avec son cousin est souvent un critère de choix pour des équipes mixtes (Java/NET).
  • NUnit : très proche de son cousin Java JUnit, il est également basé sur des attributes. Dans le monde ouvert, j’apprécie également MBUnit maintenant inclus dans le framework Gallio. Pour intégrer ces frameworks open-source dans un IDE tel que Visual Studio, je conseille test driven.net. Microsoft fournit également son propre framework,  qui ressemble beaucoup à NUnit et qui est très bien intégré dans Visual Studio. J’avoue l’utiliser très souvent. J’aime particulièrement la structuration par projet, qui fonctionne également pour tester des classes « internal ». J’aime également la facilité avec laquelle on peut écrire des tests orientés données, en prenant un fichier CSV pour indiquer les paramètres d’entrée et les paramètres de sortie.
  • Un équivalent à Mockito. Ne l’ayant pas utilisé sur un projet, la réponse risque d’être déplacée. Néanmoins, j’utilise parfois moq ou NMock. Je suis preneur d’un comparatif ;)
  • Pour la base de données, encore une fois je penche pour la facilité d’intégration et donc pour une solution SQL Server Express, ou SQL Server Compact, selon l’usage. Les deux solutions sont gratuites.

Je termine par un outil que je trouve très utile, qui est maintenant intégré à Visual Studio 2010 SP1 et qui permet de gérer des librairies externes, un maven like light : NuGet.

Entity Framework Code-First CTP5

La CTP5 de Code-First est disponible. La prochaine version annoncée pour mi 2011 sera la version finale.

J’avais présenté très rapidement Entity Framework dans ce billet en introduisant le mode fluent. La CTP5 embarque certaines fonctionnalités très intéressantes.

Je vous conseille notamment de regarder le support des annotations du namespace DataAnnotations. Ces annotations permettent de spécifier les contraintes du domaine directement dans les classes POCO. Ces contraintes seront exploitées par le modèle relationnel, par le modèle objet via Entity Framework et également par les couches d’IHM supportant ces annotations.

L’annonce de Scott Guthrie.

Categories: .NET Tags: ,

Presentation d’Entity Framework

Voici un premier billet présentant de manière générale l’outil de mapping objet relationnel proposé par Microsoft : Entity Framework. Je proposerai par la suite d’autres billets sur des points spécifiques au mapping objet relationnel tels que :

  • les identifiants
  • les associations entre entités
  • l’héritage
  • les stratégies de chargement

Afin de lever toute ambiguïté, je tiens à préciser que j’arrive du monde Hibernate, un outil de mapping objet relationnel open source reconnu et aujourd’hui normalisé avec JPA (Java Persistence API). C’est pourquoi je ferai régulièrement référence à cet outil que j’apprécie particulièrement. Ceux qui connaissent (N)Hibernate ne seront pas trop dépaysés car certains mécanismes ont été repris.

La première version d’Entity Framework ne m’a pas vraiment convaincu.

  • L’idée fondamentale qui est de séparer le modèle conceptuel (CSDL : Conceptual Schema Definition Language), du modèle logique de bases de données (SSDL : Store Schema Definition Language) en détaillant le mapping dans un schéma de liaison (MSL : Mapping Specification Language) est théoriquement très intéressant mais se révèle assez lourd dans la pratique : le designer proposé dans Visual Studio étant limité, il faut très rapidement éditer LE fichier XML manuellement qui est encore plus verbeux qu’un fichier de mapping Hibernate !
  • Par ailleurs, les objets entités étaient nécessairement très liés au framework : héritage d’implémentation, utilisation de collections propres à EF…
  • L’approche outillée était une approche relationnelle : à partir d’un modèle relationnel et EF génère des classes persistantes.

Avec la nouvelle version (Entity Framework 4), et notamment avec Entity Framework Feature CTP 3, également connu sous le nom de code-first, je commence à trouver l’outil très intéressant.

Comme son nom l’indique, code-first permet d’écrire des classes en premier, puis de générer un modèle relationnel issu de ces classes. C’est cette approche que je vous propose d’aborder dans ces billets avec la modélisation d’un système d’information (très simplifié) d’une banque. Dans une banque le client est roi, nous commencerons donc par la classe Client:

public class Client{
   public int Id { get; set;}
   public string Nom { get; set;}
   public string Prenom { get; set;}
}

Pour fournir à Entity Framework les informations de mapping, nous utiliserons le mode fluent. Pour cela, on définit généralement une classe de configuration par entité qui étend de EntityConfiguration<T>.

public class ClientConfiguration : EntityConfiguration<Client>{
   public ClientConfiguration(){

   // la propriété Id est l'identifiant de base de données
   this.Property( client => client.Id)
        .IsIdentity();

   // la propriété Nom ne peut pas être null
   // elle a une taille max de 200
   this.Property( client => client.Nom)
        .IsRequired()
        .HasMaxLength(200);
   }
}

Cette manière d’utiliser les lambdas expressions est de plus en plus fréquente en C#. On la retrouve notamment dans Fluent Nhibernate. Les fichiers de mapping XML sont contraignants à éditer et à maintenir. Les annotations sont plus simples d’utilisation mais leur présence dans nos classes POCO impliquent une forme d’adhérence vers le framework : une dépendance de compilation. Dans une application RIA avec Silverlight , il est fréquent de référencer l’assembly contenant le modèle du domaine. Mais une dépendance de compilation des classes du domaine vers un framework de mapping objet relationnel rend caduque ce référencement. Le mode fluent permet de décrire le mapping dans une assembly tierce, sans la lourdeur du XML avec en prime une vérification au moment de la compilation, de la complétion et du refactoring !

Je détaillerai dans mon prochain billet la configuration du ContextBuilder à partir de nos classes de configuration. C’est l’équivalent de la SessionFactory. Une fois configurée, cette fabrique va permettre  à EF de générer notre schéma de bases de données. Par défaut, il va créer une table Clients avec 3 colonnes :

  1. Id : la clé primaire de la table auto incrémentée
  2. Nom : un nvarchar de 200 non null
  3. Prenom

Nous avons vu dans ce premier billet la mise en place d’un mapping simple entre un POCO vers une base de données relationnelle, les éléments de mapping étant fournis dans une classe C# en mode fluent.

Categories: .NET Tags: , ,