Cet article s’adresse aux personnes connaissant déjà Entity Framework (EF) et a pour but d’être un répertoire de patrons de développement utiles dans vos phases de développement.

Je passerai très rapidement sur le fonctionnement de base (pour mémoire). Nous verrons dans un second article des outils permettant le test et la maintenance facile (teaser !)

 

Pour rappel

Contrairement aux premières versions d’Entity Framework, c’est l’approche Code First qui est privilégiée : c’est le code C# qui décrit le modèle et génère le schéma de base de données.

Bien évidemment, il existe un outil permettant de générer le code correspondant à un schéma existant.

Pour la suite, nous prendrons un exemple « from scratch »

 

Présentation du modèle

schema 1

Côté code

Chaque entité est matérialisée par une classe C# :

 

La propriété ID n’a pas besoin d’attribut pour être considéré comme l’ID de la table. De manière générale, Entity Framework Core fait beaucoup usage de conventions pour son fonctionnement.

Le schéma est codé de la manière suivante :

 

Dans la vraie vie, on ne placera pas la chaine de connexion en dur dans le code…

Pour ajouter des données, on procède comme suit :

 

 

Pour interroger la base, on utilise Linq :

 

Ici, il est important de comprendre que la requête n’est effectuée que lors de la réduction avec la méthode ToList.

De plus, la jointure avec la table de commentaire n’est pas faite. Pour effectuer la jointure, il faut utiliser la méthode Include :

 

A noter l’usage d’un using afin d’instancier le contexte dans un soucis de simplicité. Dans la pratique, on préférera l’injection dans le constructeur, surtout que dotnet core à un mécanisme d’injection fournis de base.

 

Relation Many-to-Many (M2M)

Nous venons de voir des relations One to Many (Un Post contient plusieurs Comments), mais comment implémenter une relation N-N ?

A l’heure où j’écris ces ligne, Entity Frameword Core ne permet pas l’implémentation « out of the box » des relations M2M, mais il est relativement aisé de le coder soi-même. Reprenons notre modèle :

Relation Many-to-Many

 

On ajoute l’entité Category et pour matérialiser la relation *-*, en base, nous auront une table de relation. Pour matérialiser cette table, on crée une classe :

 

Les relations entre les tables sont modélisées dans la méthode OnModelCreating, on remarquera notamment que la table de liaison n’est pas accessible directement dans le contexte et qu’il peut être assez lourd d’accéder à l’entité Category depuis l’entité Post.

Pour faciliter cela, on peut modifier notre entité de cette façon :

 

Soft Delete

Pour vos entités, il peut être intéressant de ne jamais effacer physiquement les lignes, mais de les marquer comme effacées.

Pour cela, il suffit de modifier le contexte, on n’intervient pas sur les classes d’entités.

 

Dans le contexte, on ajoute donc une propriété IsDelete sur les entités voulues. Cette propriété n’apparait qu’en base puisque les classes d’entités ne la mappent pas.

Un peu plus bas, on assure le filtrage pour que les lignes effacées ne remontent pas dans les select.

Dans la méthode SaveChangesAsync, on s’assure que la propriété soit correctement positionnée en fonction du cas (création ou effacement).

A noter qu’avec cette technique, on pourrait également implémenter un système d’audit pour savoir quel est l’utilisateur qui a fait l’action et quand.

 

Persistance d’une hiérarchie

Dans le développement objet, il est fréquent d’avoir une hiérarchie d’héritage entre les classes.

Persistance d’une hiérarchie

Pour stocker de telles données dans une base de données relationnelle, on a 2 solutions :

  • Table per Hierarchy (TPH)
    Dans ce modèle, la hiérarchie des classes est « mise à plat » dans une seule table et une colonne est crée pour reconstruire l’objet initial. On l’appelle le discriminant.
  • Table per Type (TPT)
    Ici, chaque type dispose de sa propre table

Seule TPH est supporté par Entity Framework Core, TPT est dans le backlog mais nombreux sont ceux qui considèrent ce pattern comme mauvais. Nous allons donc voir comment implémenter TPH.

On ajoute les classes héritant de notre entité de base :

 

Et on ajoute une collection pour les nouvelles entités :

 

Et c’est tout ! Entity Framework créera tout seul une colonne Discriminator dans la table Posts contenant le nom de la classe d’entité. On verra dans la deuxième partie de cet article comment modifier simplement le schéma de base de données.

 

Rendez-vous dans un prochain article où verrons comment tester notre schéma de base et comment le faire évoluer grâce aux migrations. Stay Tuned !