【问题标题】:ef core 2.1 Many To Manyef core 2.1 多对多
【发布时间】:2018-10-31 14:23:42
【问题描述】:

我有 4 个表,我正试图在 EF Core 2.1 中创建它们的关系

一部作品有一个或多个角色。例如一部制作“汉密尔顿”有一个人担任导演,

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

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

我的方向是否正确?

【问题讨论】:

    标签: c# ef-core-2.1


    【解决方案1】:

    设计还可以。但流畅的配置不是。 EF Core 不允许在 Fluent API 中使用嵌套属性,因此您的 HasKeyHasForeignKey 方法使用会导致运行时异常。

    由于您的模型符合 EF Core 约定,并且所有关系都使用两端的导航属性进行描述,因此 EF Core 将能够自动确定几乎所有没有任何流畅配置的内容,除了连接实体复合主键。它是唯一需要流畅配置的。

    虽然可以仅使用影子属性配置复合 PK(了解 FK 属性命名的 EF Core 约定,例如 public Person Person -> int PersonId):

    modelBuilder.Entity<ProductionPersonRole>()
         .HasKey("ProductionId", "PersonId", "RoleId");
    

    我建议向连接实体添加显式 FK 属性:

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

    它不仅避免了硬编码字符串的使用,而且在断开连接的情况下插入/删除链接时也非常有用。

    【讨论】:

      【解决方案2】:

      是的,只需验证数据库架构。 因为如果不正确,EF 将创建具有不同架构的数据库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-19
        • 2020-07-14
        • 1970-01-01
        • 2021-10-11
        • 2018-12-07
        • 1970-01-01
        • 2018-06-02
        • 2018-06-21
        相关资源
        最近更新 更多