繁体   English   中英

使用ID和外键的EF core 2复合主键

[英]EF core 2 composite primary key using Id and a foreign key

我有两个模型课

    public class ClassA 
    {
        public Guid Id { get; set; }        

        public IEnumerable<ClassB> ClassBs { get; set; }

    }

    public class ClassB 
    {
        public String Id { get; set; }                

    }

如何告诉实体框架使用带有ClassA.Id和ClassB.Id的复合主键创建表ClassB? 这样,我可以在ClassB表中具有相同ID的多个记录。 我不想更改ClassB来添加另一个Guid Id属性。 我也不想使用EF属性,我想将模型类与ORM框架分开。

编写您的ClassB ,如下所示:

public class ClassB 
{
    public String Id { get; set; }

    public Guid ClassAId {get; set;}

    ...............

    public ClassA ClassA  {get; set;}               

}

然后编写ClassB配置,如下所示:

public class ClassBConfiguration : IEntityTypeConfiguration<ClassB>
{
    public void Configure(EntityTypeBuilder<ClassB> builder)
    {
        builder.HasKey(b => new { b.Id, b.ClassAId });

        builder.HasOne(b => b.ClassA).WithMany(a => a.ClassBs).HasForeignKey(b => b.ClassAId);
    }
}

然后在OnModelCreating中如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        base.OnModelCreating(modelBuilder);

        modelBuilder.ApplyConfiguration(new ClassBConfiguration());
}

如果您不想在ClassB模型中引入显式的FK属性,则可以利用HasKey接收string属性名称的非lambda重载并传递影子 FK属性名称,该名称在该模型中的惯例为“ ClassAId”:

modelBuilder.Entity<ClassB>()
    .HasKey("Id", "ClassAId");

该方法的缺点之一是使用“魔术”弦。 但是可以借助nameof运算符来避免。

另一个缺点是,检索/操作ClassB对象的唯一方法是通过父ClassA对象(尽管在EF Core LINQ to Entities查询中,您可以使用EF.Property<Guid>(param, "ClassAId")访问它以进行过滤/订购/投影(如果需要)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM