J'ai recherché dans stackoverflow une solution appropriée pour générer une relation plusieurs-à-plusieurs , en utilisant EF Core, Code first et Fluent API.
Un scénario simple serait:
public class Person
{
public Person() {
Clubs = new HashSet<Club>();
}
public int PersonId { get; set; }
public virtual ICollection<Club> Clubs { get; set; }
}
public class Club
{
public Club() {
Persons = new HashSet<Person>();
}
public int ClubId { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
Veuillez me corriger si je me trompe, mais honnêtement, je ne pourrais pas trouver de question contenant une explication détaillée sur la façon de procéder en utilisant les outils décrits. Quelqu'un peut-il expliquer comment cela se fait?
EF Core 5.0 RC1 +
À partir d'EF Core 5.0 RC1, il est possible de le faire sans table de jointure explicite. EF Core est capable de configurer un mappage pour la relation plusieurs-à-plusieurs indiquée dans votre question sans vous obliger à créer un PersonClubtype.
Consultez Quoi de neuf dans EF Core 5.0, RC1, Many-to-many dans la documentation officielle pour plus d'informations.
Versions précédentes
Cela n'est pas encore possible dans EF Core sans utiliser une classe explicite pour la jointure. Voir ici pour un exemple de la façon de procéder.
Il y a un problème ouvert sur Github demandant la possibilité de le faire sans avoir besoin d'une classe explicite, mais il n'est pas encore terminé.
En utilisant votre scénario, l'exemple que j'ai lié recommande les classes d'entités suivantes:
public class Person
{
public int PersonId { get; set; }
public virtual ICollection<PersonClub> PersonClubs { get; set; }
}
public class Club
{
public int ClubId { get; set; }
public virtual ICollection<PersonClub> PersonClubs { get; set; }
}
public class PersonClub
{
public int PersonId { get; set; }
public Person Person { get; set; }
public int ClubId { get; set; }
public Club Club { get; set; }
}
Ce qui suit OnModelCreatingserait alors utilisé pour la configuration:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonClub>()
.HasKey(pc => new { pc.PersonId, pc.ClubId });
modelBuilder.Entity<PersonClub>()
.HasOne(pc => pc.Person)
.WithMany(p => p.PersonClubs)
.HasForeignKey(pc => pc.PersonId);
modelBuilder.Entity<PersonClub>()
.HasOne(pc => pc.Club)
.WithMany(c => c.PersonClubs)
.HasForeignKey(pc => pc.ClubId);
}
Assurez-vous d'aller à la question ouverte que j'ai liée et d'exprimer votre frustration si vous en ressentez le besoin.
EDIT: Le numéro ouvert suggère d'utiliser un simple Selectpour naviguer à travers cette hiérarchie quelque peu lourde. Pour passer de a PersonIdà une collection de Clubs, vous pouvez utiliser SelectMany. par exemple:
var clubs = dbContext.People
.Where(p => p.PersonId == id)
.SelectMany(p => p.PersonClubs);
.Select(pc => pc.Club);
Je ne peux pas garantir si c'est vraiment une "meilleure pratique", mais cela devrait certainement faire l'affaire et je pense qu'il est juste de dire que ce n'est pas trop moche.
La "configuration" correcte pour cela est:
public class Person
{
public int PersonId { get; set; }
public virtual ICollection<PersonClub> PersonClubs { get; set; }
}
public class Club
{
public int ClubId { get; set; }
public virtual ICollection<PersonClub> PersonClubs { get; set; }
}
public class PersonClub
{
public int PersonId { get; set; }
public Person Person { get; set; }
public int ClubId { get; set; }
public Club Club { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PersonClub>()
.HasKey(pc => new { pc.PersonId, pc.ClubId });
}
Donc, ce bloc de configuration de la "glue-table" n'est pas nécessaire comme dans l'exemple @Kirk:
modelBuilder.Entity<PersonClub>()
.HasOne(pc => pc.Person)
.WithMany(p => p.PersonClubs)
.HasForeignKey(pc => pc.PersonId);
modelBuilder.Entity<PersonClub>()
.HasOne(pc => pc.Club)
.WithMany(c => c.PersonClubs)
.HasForeignKey(pc => pc.ClubId);
Donc, chacun Persona zéro ou plus Clubset chacun Cluba zéro ou plus Persons. Comme vous l'avez dit correctement, il s'agit d'une véritable relation plusieurs-à-plusieurs.
Vous savez probablement qu'une base de données relationnelle a besoin d'une table supplémentaire pour implémenter cette relation plusieurs-à-plusieurs. La bonne chose à propos du framework d'entité, c'est qu'il reconnaît cette relation et crée cette table supplémentaire pour vous.
À première vue, il semble problématique que cette table supplémentaire ne soit pas dbSetdans votre DbContext: "Comment effectuer une jointure avec cette table supplémentaire si je n'en ai pas DbSetpour cela?".
Heureusement, vous n'avez pas besoin de mentionner cette table supplémentaire dans vos requêtes.
Si vous avez besoin d'une requête comme "Donnez-moi tous les 'Clubs' qui ... de chaque 'Personne' qui ..." ne pensez pas aux jointures. Utilisez plutôt ICollections!
Obtenez toutes les personnes "John Doe" avec tous les clubs de pays auxquels elles participent:
var result = myDbContext.Persons
.Where(person => person.Name == "John Doe")
.Select(person => new
{
PersonId = person.Id,
PersonName = person.Name,
AttendedCountryClubs = person.Clubs
.Where(club => club.Type = ClubType.CountryClub),
};
Entity Framework reconnaîtra qu'une jointure avec la table plusieurs-à-plusieurs supplémentaire est nécessaire, et effectuera cette jointure, sans que vous mentionniez cette table supplémentaire.
Inversement: obtenez tous les country clubs avec leurs personnes "John Doe":
var result = myDbContext.Clubs
.Where(club => club.Type = ClubType.CountryClub)
.Select(club => new
{
ClubId = club.Id,
ClubName = club.Name,
AnonymousMembers = club.Persons
.Where(person => person.Name == "John Doe"),
}
J'ai fait l'expérience qu'une fois que j'ai commencé à penser aux collections résultantes que je veux au lieu des jointures dont j'avais besoin pour obtenir ces collections, j'ai constaté que j'utilisais à peine les jointures. C'est le cas des relations un-à-plusieurs ainsi que des relations plusieurs-à-plusieurs. Entity Framework utilisera en interne les jointures appropriées.
Jana Duggar a été ouverte sur sa recherche de l'amour. Voici tout ce qu'elle a dit sur le sujet et sa fenêtre de mariage de cinq ans.
La star d'Outlander, Sam Heughan, a récemment révélé ce qu'il retirera du tournage pour se souvenir de Jamie Fraser, le rôle qui a fait de lui une star.
"She Loves You" a été écrite en une heure, enregistrée en une journée, et a été la chanson des Beatles avec l'une de leurs meilleures performances de leur carrière.
Dolly Parton et sa grand-mère Bessie avaient une relation spéciale. Grand-mère Parton était très malade, mais cela n'a pas empêché Dolly de lui faire des farces.
Vous pensez peut-être que le chêne ou le noyer sont résistants, mais en matière de bois les plus durs au monde, ils sont loin derrière.
L'océan regorge de beauté, mais il abrite aussi certaines des créatures marines les plus terrifiantes de la planète. Nombre de ces animaux vivent dans les profondeurs obscures et sous haute pression des abysses.
Que vous affrontiez des créatures hostiles ou vous prépariez pour des affrontements PvP, connaître les meilleurs enchantements d'épée dans Minecraft peut vous donner un avantage considérable. Enchanter vos épées vous permet d'infliger plus de dégâts, d'augmenter le butin des créatures et d'accroître leur durabilité.
Quand on parle de pays socialistes, on imagine souvent un contrôle total de l'État et l'absence de propriété privée. Mais en réalité, les économies socialistes sont très diverses.
« Enfants » laisse tomber un caméo de grand nom et des nouvelles dévastatrices
Ce RAV4 est déclaré en excellent état et est prêt pour un jeu de chaises musicales.
Des images de drones ont montré des pompiers semblant lutter pour éteindre l'incendie.
Eyes of Wakanda est directement lié au MCU, ainsi que des mises à jour sur X-Men '97, What If..., Daredevil, et plus encore.
Ava Gardner a été mariée à Mickey Rooney et Frank Sintra, et a fréquenté plusieurs autres stars d'Hollywood. Voici un aperçu de l'histoire amoureuse d'Ava Gardner.
John Cleese a épousé sa femme, Jennifer Wade, en 2012. Voici tout ce qu'il faut savoir sur la femme de John Cleese, Jennifer Wade.
Craig Melvin a épousé la présentatrice sportive Lindsay Czarniak en 2011. Voici tout ce qu'il faut savoir sur la femme de Craig Melvin.
Maggie Gyllenhaal et Peter Sarsgaard se sont mariés en 2009 et partagent deux filles ensemble. Voici une chronologie complète de leur relation.
Ça me frappe tout à coup, comme c'est si souvent le cas C'est à nouveau le milieu du chemin <Non, pas celui du Pacifique, toi marron, celui du carnaval> Chaque gros titre fort… ..
En 2022, avec la sortie de GPT-3, la compétence en écriture semble devenir moins importante. Avec l'IA, les personnes ayant une mauvaise écriture peuvent également générer du personnel de qualité.
Dans le monde rapide et compétitif d'aujourd'hui, la carrière d'une personne joue un rôle important dans la croissance personnelle, la stabilité financière et la satisfaction globale de la vie. Cependant, de nombreuses personnes se retrouvent prises dans un cycle incessant de stagnation et d'insatisfaction, dépérissant progressivement dans leur vie professionnelle.
La semaine dernière, j'ai remarqué un communiqué de presse, envoyé via PressGazette (un site Web d'information britannique). L'article annonçait qu'Acast, la société d'hébergement et de publicité de podcasts de Scandi, dirigerait un consortium d'éditeurs "probablement les plus influents" du podcasting.