Voir le flux RSS

Blog de Hinault Romaric (.NET Core, ASP.NET Core, Azure, DevOps)

[Actualité] Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First

Note : 2 votes pour une moyenne de 5,00.
par , 27/04/2017 à 04h41 (828 Affichages)
Dans les versions précédentes d’Entity Framework, pour matérialiser une relation de type plusieurs à plusieurs avec l’approche Code First, il suffisait simplement de disposer dans chaque classe entité, une propriété représentant une collection d’objets de la classe entité en lien.

Prenons par exemple les classes entités Categorie et Post ci-dessous :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Categorie
  {
 
       public int Id { get; set; }
      public string Libelle { get; set; }
      public string UrlSlug { get; set; }
 
      public ICollection<Post> Posts { get; set; }
  }
 
 
 public class Post
  {
 
        public int Id { get; set; }
        public string Titre { get; set; }
        public string Contenu { get; set; }
        public DateTime DatePublication { get; set; }
        public TimeSpan HeurePublication { get; set; }
        public string UrlSlug { get; set; }
 
       public ICollection<Categorie> Categories { get; set; }
  }

La définition de ces classes ainsi était suffisante pour qu’Entity Framework puisse matérialiser une relation de type plusieurs à plusieurs.

Cependant, si vous procédez à la génération de votre base de données en utilisant Entity Framework Core, vous obtiendrez l’erreur suivante :

Unable to determine the relationship represented by navigation property 'Categorie.Posts' of type 'ICollection<Post>'. Either manually configure the relationship, or ignore this property from the model.
Entity Framework Core n’offre pas encore un support des relations de type plusieurs à plusieurs identique à la version précédente. Pour pallier cela, vous êtes obligés de créer une classe association PostCategorie à votre modèle et procéder à deux mappages séparés un à plusieurs :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
  public class PostCategorie
  {
 
      public int PostId { get; set; }
      public Post Post { get; set; }
 
      public int CategorieId { get; set; }
      public Categorie Categorie {get; set;}  
  }

Les classes entités Categorie et Post doivent être modifiées comme suit :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Categorie
  {
 
       public int Id { get; set; }
      public string Libelle { get; set; }
      public string UrlSlug { get; set; }
 
      public ICollection<PostCategorie> PostCategories { get; set; }
  }
 
 public class Post
  {
 
        public int Id { get; set; }
        public string Titre { get; set; }
        public string Contenu { get; set; }
        public DateTime DatePublication { get; set; }
        public TimeSpan HeurePublication { get; set; }
        public string UrlSlug { get; set; }
 
       public ICollection<PostCategorie> PostCategories { get; set; }
 
  }

Une fois cela fait, vous devez utiliser Fluent API pour Entity Framework Core pour configurer la relation et permettre de ce fait le mappage adéquat :


Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostCategrie>()
            .HasKey(t => new { t.PostId, t.CategorieId });
 
        modelBuilder.Entity<PostCategrie>()
            .HasOne(pt => pt.Post)
            .WithMany(p => p.PostCategries)
            .HasForeignKey(pt => pt.PostId);
 
        modelBuilder.Entity<PostCategrie>()
            .HasOne(pt => pt.Categorie)
            .WithMany(t => t.PostCategries)
            .HasForeignKey(pt => pt.CategorieId);
    }

Cela fait, vous pouvez à nouveau générer votre base de données. Vous allez remarquer la présence de la table association avec les contraintes d’intégrité adéquates.

Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Viadeo Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Twitter Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Google Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Facebook Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Digg Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Delicious Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog MySpace Envoyer le billet « Entity Framework Core : configuration des relations plusieurs à plusieurs avec Code First » dans le blog Yahoo

Mis à jour 27/04/2017 à 19h40 par Malick (ajout espaces insécables)

Catégories
DotNET , C# , .NET Core , ASP.NET Core , Entity Framework

Commentaires

  1. Avatar de ypelissier
    • |
    • permalink
    Bonjour,
    La surprise fût de taille lorsque j'ai voulu faire une liaison Many-2-Many entre 2 tables... OK, j'ai la solution, elle est implémentée et ça fonctionne bien (en tout cas pour le moment ça compile, ça me crée bien les tables et les clés étrangères donc a priori tout va bien).
    Mais ce message d'erreur ne vient pas seulement lorsqu'une liaison M2M est faite. Je suis à nouveau devant ce message d'erreur parce que j'ai 2 relations One-2-Many entre 2 tables (même sens).

    Explication :
    Dans mon modèle de données fonctionnel, j'ai un utilisateur qui fait (ou doit faire) des actions (premier lien vers les utilisateurs qui fonctionne nickel) mais je dois également savoir qui a planifié ces actions (et hop second lien vers les utilisateurs). Là ça coince (bien sûr je n'ai pas mis le même nom dans la classe mais ça pointe bien vers la même table). D'ailleurs, dès que j'en mets un en commentaire, ça passe nickel de nouveau.

    Auriez-vous une idée de comment gérer la situation ?

    Merci

    P.S. : Sinon, bon article que j'ai complété avec celui-ci (en anglais) : https://blog.oneunicorn.com/2017/09/...-1-the-basics/
  2. Avatar de ypelissier
    • |
    • permalink