流利的API,实体框架核心中的多对多 [英] Fluent API, many-to-many in Entity Framework Core

查看:83
本文介绍了流利的API,实体框架核心中的多对多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在stackoverflow上搜索了使用EF Core,Code first和Fluent API生成多对多关系的适当解决方案。



一个简单的情况是:

 公共类Person 
{
public Person() {
Clubs = new HashSet< Club>();
}
public int PersonId {get;组; }
公共虚拟ICollection< Club>俱乐部{组; }
}

public class Club
{
public Club(){
Persons = new HashSet< Person>();
}
public int ClubId {get;组; }
公共虚拟ICollection< Person>人{组; }
}

如果我做错了,请纠正我,但老实说我找不到一个问题包含有关如何使用描述的工具执行此操作的详细说明。
谁能解释这是怎么做的?

解决方案

如果不使用显式类,这在EF Core中尚不可能。加入。有关如何执行此操作的示例,请参见此处。 p>

在Github上有一个打开的 issue 要求有能力执行此操作而无需显式类,但尚未完成。



使用您的方案,我链接的示例将建议以下内容实体类:

 公共类Person 
{
public int PersonId {get;组; }
公共虚拟ICollection< PersonClub> PersonClubs {get;组; }
}

public class Club
{
public int ClubId {get;组; }
公共虚拟ICollection< PersonClub> PersonClubs {get;组; }
}

public class PersonClub
{
public int PersonId {get;组; }
public Person Person {get;组; }
public int ClubId {get;组; }
public Club Club {get;组; }
}

以下 OnModelCreating 然后将用于设置:

 受保护的覆盖无效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);
}

请务必访问我链接的公开问题,并表达您的无奈。



编辑:未解决的问题建议使用简单的 Select 来浏览此繁琐的层次结构。为了从 PersonId Club s的集合,可以使用 SelectMany 。例如:

  var clubs = dbContext.People 
.Where(p =&>; p.PersonId == id)
.SelectMany(p => p.PersonClubs);
.Select(pc => pc.Club);

我不能保证这是否真的是最佳实践,但它当然应该做到这个技巧,我认为可以说它并不难看。


I've searched stackoverflow for a proper solution on generating a many-to-many relationship, using EF Core, Code first and Fluent API.

A simple scenario would be:

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; }
}

Please correct me if im wrong but I could honestly not find a question that contains an elaborate explanation on how to do this using the described tools. Can anyone explain how this is done?

解决方案

This is not yet possible in EF Core without using an explicit class for the join. See here for an example of how to do that.

There's an open issue on Github asking for the ability to do this without the need for an explicit class, but it has not yet been completed.

Using your scenario, the example I linked would recommend the following entity classes:

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; }
}

The following OnModelCreating would then be used for setup:

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);
}

Be sure to go to the open issue I linked and voice your frustration if you feel the need.

EDIT: The open issue suggests using a simple Select to navigate through this somewhat cumbersome hierarchy. In order to get from a PersonId to a collection of Clubs, you can use SelectMany. e.g.:

var clubs = dbContext.People
    .Where(p => p.PersonId == id)
    .SelectMany(p => p.PersonClubs);
    .Select(pc => pc.Club);

I can't vouch for whether this is truly a "best practice", but it should certainly do the trick and I think its fair to say it's not overly ugly.

这篇关于流利的API,实体框架核心中的多对多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆