entity framework如何表示这种关系,一个table被多个table引用
How does entity framework represend this relationship, one table reference by multiple tables
entity framework代码如何首先定义一个这样的table结构
Structure
class A
{
PK
Name1
List<ClassC>
}
class B
{
PK
Name2
List<ClassC>
}
class C
{
PK
ClassA
ClassB
}
您当前的 class 结构与图片上的 ERD 不一致。
关系形成图片:
C可以和很多A相连,但是A只能和一个C相连(1:M)
C可以和很多B相连,但是B只能和一个C相连(1:M)
下面的结构应该有效:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
// Fully defined relationship
public int C_Id { get; set; }
public C C_ojb { get; set; }
}
public class B
{
public int Id { get; set; }
public string Name { get; set; }
// Fully defined relationship
public int C_Id { get; set; }
public C C_obj { get; set; }
}
public class C
{
public int Id { get; set; }
public string Name { get; set; }
// Fully defined relationship
public List<A> As { get; set; }
public List<B> Bs { get; set; }
}
我建议您访问此页面:
https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key
https://www.learnentityframeworkcore.com/
您在图表中勾勒出的关系可能不会如您所愿。
如果 TableC 上的 ParentId 旨在指向 Table A 上的 Id 或 Table B 上的 Id,那是行不通的。匹配记录必须在 Table A 和 Table B 中。
SQL 服务器将允许这样做,并且 EF(至少 EF6)将支持这一点,只要在实体中声明了 ParentId 并将其设置为两个关系的 FK。影子属性(使用 Map(x => x.MapKey())
的 EF6)不起作用,因为它希望对两个关系使用相同的名称,至少在 EF6 中是这样。在 EF Core 中,您需要测试这是否完全受支持。
举以下两个例子:
我们有一个学校系统,我们有学生 (Table A) 和教师 (Table B)。学生和老师都有一个或多个地址(Table C)
一个地址可以属于学生,也可以属于教师,很少同时属于学生和教师。因此,像您在指向学生和教师 table 的 ParentID 之间使用 FK 指定的 table 结构没有多大意义。 Parent ID 5 必须同时存在于 Students 和 Teachers 中,而不是一个或另一个,即使可以,您也不知道地址是引用 Student 还是 Teacher。从数据库的角度来看,您可以添加一个 ParentType 来指示 ParentId 是指学生还是教师,但是您必须删除 ParentId 上的 FK,因为它不能指向两个 tables 并且期望只找到一个或另一个。这变成了一种隐含的关系,效率不高,不能用约束来强制执行。 (即确保 ParentId 实际上指向 table 或正确的 table 等中的一行)它也不能映射为 EF 中的关系。
这种方法的工作方式是将 Student 和 Teacher 组合成一个 Person table,并使用角色标识符之类的东西来判断 Person 是 Student 还是 Teacher。通过这种方式,Address table 可以合法地拥有一个 PersonId。 (而不是 ParentId)在 EF 中,您仍然可以将 Student 和 Teacher classes 通过 Person base class 映射到 Person table,使用 Role 作为鉴别器。在 EF 中,这称为 Table-per-Hierarcy 继承。
这适用于 class 与公共实体(如地址)具有合理关系的实体 table。我们可以在基class table 和相关的多边table 之间建立一对多关系。如果您希望学生、教师和学校拥有一个或多个地址,它就不太适用。 (即学校可以有校园)学校不是“人”,也不应被视为一个人。即使使用 relatable 实体,当我们想要几个特定于学生的字段与特定于教师的其他字段时,这也可能是有问题的。这需要向 Person table 添加一堆可为 null 的字段,或者从 Person 到 StudentInfo 或 TeacherInfo table 的 0-1 关系以保存学生或教师的特定详细信息。
我们有不相关的实体,需要一对多的关系,比如学生 table、老师 table 和学校 table,所有这些都与一个有关或更多地址记录,更好的选择是采用多对多关系。
学生
StudentAddress (StudentId, AddressId)
老师
TeacherAddress (TeacherId, AddressId)
学校
SchoolAddress (SchoolId, AddressId)
地址
在这种情况下,如果多对多 table 只包含作为复合 PK 的 FK 而没有其他列,则学生、教师或学校可以拥有地址实体的集合,并且您使用的是 EF6 或 EF Core 5。(我相信支持这一点)早期版本的 EF Core 不支持自动通过未映射的连接 table 进行引用,因此这需要通过映射的连接实体声明集合。 (即 ICollection<StudentAddress>
)
地址可以包含对学生/教师/学校集合的引用,但通常我不会费心映射这些,除非确实有必要。作为多对多关系,这将合法地允许同一个地址属于多个学生,而在适当的一对多关系中是不允许的。
为了实施正确的一对多,Address table 将被删除,地址字段将放入每个 StudentAddress、TeacherAddress 和 SchoolAddress table 中。
entity framework代码如何首先定义一个这样的table结构 Structure
class A
{
PK
Name1
List<ClassC>
}
class B
{
PK
Name2
List<ClassC>
}
class C
{
PK
ClassA
ClassB
}
您当前的 class 结构与图片上的 ERD 不一致。
关系形成图片:
C可以和很多A相连,但是A只能和一个C相连(1:M)
C可以和很多B相连,但是B只能和一个C相连(1:M)
下面的结构应该有效:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
// Fully defined relationship
public int C_Id { get; set; }
public C C_ojb { get; set; }
}
public class B
{
public int Id { get; set; }
public string Name { get; set; }
// Fully defined relationship
public int C_Id { get; set; }
public C C_obj { get; set; }
}
public class C
{
public int Id { get; set; }
public string Name { get; set; }
// Fully defined relationship
public List<A> As { get; set; }
public List<B> Bs { get; set; }
}
我建议您访问此页面:
https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key
https://www.learnentityframeworkcore.com/
您在图表中勾勒出的关系可能不会如您所愿。
如果 TableC 上的 ParentId 旨在指向 Table A 上的 Id 或 Table B 上的 Id,那是行不通的。匹配记录必须在 Table A 和 Table B 中。
SQL 服务器将允许这样做,并且 EF(至少 EF6)将支持这一点,只要在实体中声明了 ParentId 并将其设置为两个关系的 FK。影子属性(使用 Map(x => x.MapKey())
的 EF6)不起作用,因为它希望对两个关系使用相同的名称,至少在 EF6 中是这样。在 EF Core 中,您需要测试这是否完全受支持。
举以下两个例子: 我们有一个学校系统,我们有学生 (Table A) 和教师 (Table B)。学生和老师都有一个或多个地址(Table C)
一个地址可以属于学生,也可以属于教师,很少同时属于学生和教师。因此,像您在指向学生和教师 table 的 ParentID 之间使用 FK 指定的 table 结构没有多大意义。 Parent ID 5 必须同时存在于 Students 和 Teachers 中,而不是一个或另一个,即使可以,您也不知道地址是引用 Student 还是 Teacher。从数据库的角度来看,您可以添加一个 ParentType 来指示 ParentId 是指学生还是教师,但是您必须删除 ParentId 上的 FK,因为它不能指向两个 tables 并且期望只找到一个或另一个。这变成了一种隐含的关系,效率不高,不能用约束来强制执行。 (即确保 ParentId 实际上指向 table 或正确的 table 等中的一行)它也不能映射为 EF 中的关系。
这种方法的工作方式是将 Student 和 Teacher 组合成一个 Person table,并使用角色标识符之类的东西来判断 Person 是 Student 还是 Teacher。通过这种方式,Address table 可以合法地拥有一个 PersonId。 (而不是 ParentId)在 EF 中,您仍然可以将 Student 和 Teacher classes 通过 Person base class 映射到 Person table,使用 Role 作为鉴别器。在 EF 中,这称为 Table-per-Hierarcy 继承。
这适用于 class 与公共实体(如地址)具有合理关系的实体 table。我们可以在基class table 和相关的多边table 之间建立一对多关系。如果您希望学生、教师和学校拥有一个或多个地址,它就不太适用。 (即学校可以有校园)学校不是“人”,也不应被视为一个人。即使使用 relatable 实体,当我们想要几个特定于学生的字段与特定于教师的其他字段时,这也可能是有问题的。这需要向 Person table 添加一堆可为 null 的字段,或者从 Person 到 StudentInfo 或 TeacherInfo table 的 0-1 关系以保存学生或教师的特定详细信息。
我们有不相关的实体,需要一对多的关系,比如学生 table、老师 table 和学校 table,所有这些都与一个有关或更多地址记录,更好的选择是采用多对多关系。
学生
StudentAddress (StudentId, AddressId)
老师
TeacherAddress (TeacherId, AddressId)
学校
SchoolAddress (SchoolId, AddressId)
地址
在这种情况下,如果多对多 table 只包含作为复合 PK 的 FK 而没有其他列,则学生、教师或学校可以拥有地址实体的集合,并且您使用的是 EF6 或 EF Core 5。(我相信支持这一点)早期版本的 EF Core 不支持自动通过未映射的连接 table 进行引用,因此这需要通过映射的连接实体声明集合。 (即 ICollection<StudentAddress>
)
地址可以包含对学生/教师/学校集合的引用,但通常我不会费心映射这些,除非确实有必要。作为多对多关系,这将合法地允许同一个地址属于多个学生,而在适当的一对多关系中是不允许的。
为了实施正确的一对多,Address table 将被删除,地址字段将放入每个 StudentAddress、TeacherAddress 和 SchoolAddress table 中。