我使用的是EF Core,我需要将子实体映射到同一张表,因为它们的类型相同。
想象一下下面的类层次结构场景:
public class Grandpa
{
public Guid Id { get; set; }
public Father Robert { get; set; }
public Father Jack { get; set; }
}
public class Father
{
public Guid Id { get; set; }
// I use this to reference Grandpa
public Guid GrandpaId { get; set; }
public List<Son> MySons { get; set; }
}
public class Son
{
public Guid Id { get; set; }
// I use this to reference Father
public Guid FatherId { get; set; }
public string Name { get; set; }
}
现在问题如下:在我的场景中(上面是复制我的真实场景的抽象),我无法将Robert
和Jack
做成一个数组-它们需要分开放置。另一件事是,Grandpa
实体拥有2个Father
实体,每个Father
实体拥有Son
实体的列表。
我想告诉ModelBuilder以这样的方式生成表:所有Father
实体有一个表,所有Son
实体有一个表-因为它们都是相同的实体,并且永远不要将它们放在不同的表中,因为它们的主键和外键(ID)清楚地指出了它们属于谁。
现在,您知道,在普通SQL中,很容易实现这种结构,为此编写SQL代码非常简单。但是,如何使用EF Core?
我尝试过:
1)在每个实体中的模型构建器中指定所有主键和外键 2)使用
在ModelBuilder中设置拥有的属性层次结构modelBuilder.Entity<Father>()
.ToTable("Fathers");
modelBuilder.Entity<Son>()
.ToTable("Sons");
modelBuilder.Entity<Grandpa>(g =>
{
x.OwnsOne(y => y.Robert, z =>
{
z.OwnsMany(a => a.MySons, b =>
{
b.HasKey(k=>k.Id);
b.ToTable("Sons");
});
z.ToTable("Fathers");
});
x.OwnsOne(y => y.Jack, z =>
{
z.OwnsMany(a => a.MySons, b =>
{
b.HasKey(k=>k.Id);
b.ToTable("Sons");
});
z.ToTable("Fathers");
});
});
但是,有错误提示:
Cannot use table 'Fathers' for entity type 'Grandpa.Father#Robert' since it is being used for entity type 'Grandpa.Father#Jack' and there is no relationship between their primary keys.
我必须提到这些实体是同一DbContext
的一部分-最好保持不变。
EF Core映射实体或映射实体失败的方式是错误的-如果删除表名称规范,它只会为我的相同类型的实体创建单独的表,这是错误的。我什至没有在不同的名称空间中声明/复制相同的实体/进行复制,但实际上是相同的名称空间,相同的实体,Grandpa
实体有两个Father
实体,每个{ {1}}实体有一个Father
。