C# ef核心2.1多对多
我在EF Core 2.1中创建了4个表,以及它们之间的关系 一部作品中有一个或多个角色。e、 g.制作“汉密尔顿”有一个人担任导演C# ef核心2.1多对多,c#,ef-core-2.1,C#,Ef Core 2.1,我在EF Core 2.1中创建了4个表,以及它们之间的关系 一部作品中有一个或多个角色。e、 g.制作“汉密尔顿”有一个人担任导演 Production ProductionId Name ------------ ----------- PR1 Hamilton Person PersonId Name -------- ----------- P1 Rick P2
Production
ProductionId Name
------------ -----------
PR1 Hamilton
Person
PersonId Name
-------- -----------
P1 Rick
P2 Chris
P3 Dan
Role
RoleId Name
---------- -----------
R1 Director
R2 Choreographer
R3 Actor
ProductionRolePerson
ProductionId PersonId RoleId
------------ -------- ------
PR1 P1 (Rick) R1 (Director)
PR1 P2 (Chris) R2 (Choreographer)
PR1 P3 (Dan) R3 (Actor)
Production
| 1
| *
ProductionPersonRole
| * | *
| 1 | 1
Person Role
我想不出建立一对多关系的正确方法
以下是我开设的课程:
public class Production
{
public int ProductionId { get; set; }
public List<ProductionPersonRole> Roles { get; set; }
}
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<ProductionPersonRole> ProductionPersonRoles { get; set; }
}
public class Role
{
public int RoldId { get; set; }
public string Name {get;set;}
public ICollection<ProductionPersonRole> Jobs { get; set; }
}
public class ProductionPersonRole
{
public Production Production { get; set; }
public Person Person { get; set; }
public Role Role { get; set; }
}
公共类制作
{
public int ProductionId{get;set;}
公共列表角色{get;set;}
}
公共阶层人士
{
公共int PersonId{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共ICollection ProductionPersonRoles{get;set;}
}
公共阶级角色
{
公共整数{get;set;}
公共字符串名称{get;set;}
公共ICollection作业{get;set;}
}
公共类ProductionPersonRole
{
公共生产{get;set;}
公众人物{get;set;}
公共角色{get;set;}
}
以下是DbContext类:
public class MyContext : DbContext
{
public DbSet<Production> Productions { get; set; }
public DbSet<ProductionPersonRole> ProductionPersonRoles { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Person> Persons { get; set; }
public MyContext(): base()
{
}
public MyContext(DbContextOptions options): base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ProductionPersonRole>()
.HasKey(ppr => new {ppr.Production.ProductionId, ppr.Person.PersonId, ppr.Role.RoldId});
modelBuilder.Entity<ProductionPersonRole>()
.HasOne(ppr => ppr.Production)
.WithMany(ppr => ppr.Roles)
.HasForeignKey(ppr => ppr.Production.ProductionId);
modelBuilder.Entity<ProductionPersonRole>()
.HasOne(ppr => ppr.Person)
.WithMany(ppr => ppr.ProductionPersonRoles)
.HasForeignKey(ppr => ppr.Person.PersonId);
modelBuilder.Entity<ProductionPersonRole>()
.HasOne(ppr => ppr.Role)
.WithMany(ppr => ppr.Jobs)
.HasForeignKey(ppr => ppr.Role.RoleId);
base.OnModelCreating(modelBuilder);
}
}
公共类MyContext:DbContext
{
公共DbSet产品{get;set;}
公共数据库集ProductionPersonRoles{get;set;}
公共数据库集角色{get;set;}
公共DbSet Persons{get;set;}
public MyContext():base()
{
}
公共MyContext(DbContextOptions):基本(选项)
{
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(ppr=>new{ppr.Production.ProductionId,ppr.Person.PersonId,ppr.RoldId});
modelBuilder.Entity()
.HasOne(ppr=>ppr.Production)
.WithMany(ppr=>ppr.Roles)
.HasForeignKey(ppr=>ppr.Production.ProductionId);
modelBuilder.Entity()
.HasOne(ppr=>ppr.Person)
.WithMany(ppr=>ppr.ProductionPersonRoles)
.HasForeignKey(ppr=>ppr.Person.PersonId);
modelBuilder.Entity()
.HasOne(ppr=>ppr.Role)
.WithMany(ppr=>ppr.Jobs)
.HasForeignKey(ppr=>ppr.Role.RoleId);
基于模型创建(modelBuilder);
}
}
我的方向正确吗 是的,只需验证数据库体系结构即可。
因为如果不正确,EF将创建具有不同架构的DB。设计正常。但流畅的配置并非如此。EF Core不允许在fluent API中使用嵌套属性,因此您的
HasKey
和HasForeignKey
方法使用将导致运行时异常
由于您的模型符合EF Core约定,并且所有关系都在两端使用导航属性进行描述,EF Core将能够自动确定几乎所有内容,而无需任何流畅的配置,除了连接实体复合主键。它是唯一需要流畅配置的
虽然可以仅使用影子属性配置复合PK(了解FK属性命名的EF核心约定,例如public Person-Person
->int PersonId
):
并改为使用以下配置:
modelBuilder.Entity<ProductionPersonRole>()
.HasKey(ppr => new { ppr.ProductionId, ppr.PersonId, ppr.RoleId });
modelBuilder.Entity()
.HasKey(ppr=>new{ppr.ProductionId,ppr.PersonId,ppr.RoleId});
它不仅可以避免使用硬编码字符串,而且在断开连接的情况下插入/删除链接时也非常有用
public class ProductionPersonRole
{
public int ProductionId { get; set; }
public int PersonId { get; set; }
public int RoleId { get; set; }
public Production Production { get; set; }
public Person Person { get; set; }
public Role Role { get; set; }
}
modelBuilder.Entity<ProductionPersonRole>()
.HasKey(ppr => new { ppr.ProductionId, ppr.PersonId, ppr.RoleId });