web-dev-qa-db-fra.com

Entity Framework Core: relation plusieurs-à-plusieurs avec la même entité

J'essaie de cartographier la relation plusieurs-à-plusieurs avec la même entité. L'entité User possède un champ de données IList<User> Pour Contacts, qui stocke les contacts/amis des utilisateurs:

public class User : DomainModel
{
    public virtual IList<User> Contacts { get; protected set; }
    //irrelevant code omitted
}

Lorsque j'essaie d'utiliser une API fluide pour mapper cette relation plusieurs à plusieurs, cela me pose des problèmes. Apparemment, lorsque j'utilise HasMany() sur la propriété user.Contacts, Il n'y a pas de méthode WithMany() pour appeler ensuite. L'intellisense de Visual Studio affiche uniquement WithOne(), mais pas WithMany().

modelBuilder.Entity<User>().HasMany(u => u.Contacts).WithMany() 
// gives compile time error: CS1061 'CollectionNavigationBuilder<User, User>' does not contain a definition for 'WithMany' and no extension method 'WithMany' accepting a first argument of type 

Alors pourquoi cela se produit-il? Y a-t-il quelque chose que j'ai fait de mal pour cartographier cette relation plusieurs-à-plusieurs?

16
Lord Yggdrasill

Alors pourquoi cela se produit-il? Y a-t-il quelque chose que j'ai fait de mal pour cartographier cette relation plusieurs-à-plusieurs?

Non, tu n'as rien fait de mal. Ce n'est tout simplement pas pris en charge . État actuel ici .

Les relations plusieurs à plusieurs sans classe d'entité pour représenter la table de jointure ne sont pas encore prises en charge. Cependant, vous pouvez représenter une relation plusieurs-à-plusieurs en incluant une classe d'entité pour la table de jointure et en mappant deux relations un-à-plusieurs distinctes.

Avec EF-Core, vous devez créer l'entité pour la table de mappage. Tels que UserContacts. Un exemple complet dans le docs , comme mentionné dans les commentaires. Je n'ai pas réellement testé le code ci-dessous, mais il devrait ressembler à ceci:

public class UserContacts
{
    public int UserId { get; set; } 
    public virtual User User { get; set; }

    public int ContactId { get; set; } // In lack of better name.
    public virtual User Contact { get; set; }
}

public class User : DomainModel
{
    public List<UserContacts> Contacts { get; set; }
}

Et votre modelBuilder.

  modelBuilder.Entity<UserContacts>()
        .HasOne(pt => pt.Contact)
        .WithMany(p => p.Contacts)
        .HasForeignKey(pt => pt.ContactId);

    modelBuilder.Entity<UserContacts>()
        .HasOne(pt => pt.User)
        .WithMany(t => t.Contacts)
        .HasForeignKey(pt => pt.UserId);
23
smoksnes