如何使用EF Core将单一实体映射到多个表的正确方法?

摘要:把一个实体类型映射到多个表,官方叫法是 Entity splitting,这个称呼有点难搞,要是翻译为“实体拆分”或“拆分实体”,你第一感觉会不会认为是把一个表拆分为多个实体的意思。可它的含义是正好相反。为了避免大伙伴们产生误解,老周直接叫
把一个实体类型映射到多个表,官方叫法是 Entity splitting,这个称呼有点难搞,要是翻译为“实体拆分”或“拆分实体”,你第一感觉会不会认为是把一个表拆分为多个实体的意思。可它的含义是正好相反。为了避免大伙伴们产生误解,老周直接叫它“一个实体映射到多个表”,虽然不言简,但很意赅。 把一个实体类对应到数据库中的多个表,本质上是啥呢?一对一,是不是?举个例子,看图。 恭喜你猜对了,正如上图所示,假设老周收了几个徒弟,上述三个表其实都是【学生】实体类拆开的。第一个表是学生的基础信息,第二个表是补充信息,第三个表是学生的联系方式。第二、三个表中的行必须与第一个表中的行一一对应。 基于这样的理解,咱们可以得出:第一个表有主键A,第二个表有个外键FA引用主键A,第三个表有个外键FB引用主键A。同时,考虑到第二、三个表中的数据是完全依赖第一个表的,所以,第二、三个表中可以把主键和外键设定为同一个列。说人话就是有一列既做当前表的主键,也做外键引用第一个表。这使得第二、三个表中每一条记录的主键列的值必须与第一个表中的主键列相同。 下面咱们举个例子说明一下。假设有这样一个实体。 /// <summary> /// 宠物 /// </summary> public class Pet { /// <summary> /// 主键 /// </summary> public int PetId { get; set; } /// <summary> /// 昵称 /// </summary> public string NickName { get; set; } = "天外物种"; /// <summary> /// 体重 /// </summary> public float? Weight { get; set; } /// <summary> /// 体长 /// </summary> public int? Length { get; set; } /// <summary> /// 毛色 /// </summary> public string? Color { get; set; } /// <summary> /// 分类 /// </summary> public string? Category { get; set; } /// <summary> /// 爱好 /// </summary> public string[] Hobbies { get; set; } = []; /// <summary> /// 性格 /// </summary> public string? Temperament { get; set; } } 于是我有个想法,把这个实体映射到一个表中好像太长,拆开为三个表多好。 1、基本信息。ID,名称,宠物类别; 2、基础特征。毛色,体长体重等; 3、额外信息。爱好,性格等。
阅读全文