3 回答
TA贡献2065条经验 获得超13个赞
我有博士学位 在cs中-在数据库方面,因此此答案与程序员的观点有所不同。就奥利弗·哈纳皮(Oliver Hanappi)而言,如果它不是替代钥匙,它有时可能会更改。例如,自然键或复合键。例如。有可能在美国更改您的SSN。但是多年以来,许多程序员会认为这是一个不可更改的密钥,因此会使用它。更改由外键组成的复合主键更为常见。
我正在处理具有三元关系的数据库。特别是三个实体(外键是其各自表中的替代主键)。但是,要在更改第三个实体的同时保留两个实体之间的关系,需要更改交集表的一部分(在MSDN上也称为纯联接表)主键。这是一个有效的设计,只能通过删除三元关系交叉表并将其替换为两个二进制关系表(它们可能具有自己的代理键)来改进。EF会处理这个罚款。此设计更改将创建(Many-> many)-> many或Parent1-Parent2-> Child-grandchild模型(如果不清楚,请阅读下面的示例)。实体框架可以很好地解决这个问题,因为每个关系实际上都是一对多的关系。但是从数据库角度来看,这是一个疯狂的设计。让我给你举个例子。
考虑课程,教室和讲师在班级中彼此关联。类可以包括:CourseID,ClassroomID,InstructorID作为外键,并且包含一个包含所有三个的合成主键。尽管一个清晰,简洁的三元模型(三向关系),我们可以将其分解为二元关系。这将提供两个相交表。添加代理密钥将满足EF,如下所示:
类(SurrogateKeyClass,InstructorID,CourseID)
ClassRoomUsed(SurrogateKeyClassroomUsed,SurrogateKeyClass,ClassRoomID)
这种设计的问题在于,我们可能多次关联同一课程和讲师,而先前的模型避免了这种情况。为避免此问题,您可以在数据库中为两个ID字段的唯一性添加一个约束,但是为什么当您只处理代理键开始时为什么要这样做呢?但是,据我所知,此解决方案将发挥最佳作用。但是,这不是逻辑数据库设计,因为DB中需要自然的唯一约束。
但是,如果您不想更改数据库或无法更改数据库,这是第二种解决方案:交集/关联表就是这样,将两个或多个实体链接在一起的链接。如果一个更改,请删除该关联,然后重新创建一个具有适当外键(导航属性)的新关联。这意味着将不允许您在任何关系中都要求有子实体,但这是非常普遍的。
我建议,实体框架(将来)允许我们中那些可以设计优雅的数据库模型的人在需要时更改交集/关联表中的键的部分!
另一个免费示例:
考虑一个学生,课程,年级协会。学生通过成绩与课程相关联。通常,这是学生与课程之间的多对多关联,在关联表中有一个称为“等级”的附加字段(关联表具有有效数据,例如等级,交集表没有有效载荷,在MSDN中被称为纯连接表,位于在一个地方租赁):
学生(StudentID,....)
课程(CourseID,...)
参加(StudentID,CourseID,年级)
如果某人从下拉菜单中犯了一个数据输入错误,并将学生置于错误的班级,您希望他们稍后通过再次选择该下拉菜单并选择其他课程来进行更改。在后台,您将需要从Takeing表中删除EF对象,然后重新创建它,而不会失去一个分数(如果有一个分数)。只需更改外键CourseID似乎是一个更好的选择。如果这似乎是人为的,请提出自己的协会,但是作为教授,这对我来说很自然。
结论:当存在一系列关系时,最好不要允许级联和/或更改FK,但是即使在一般情况下不建议将其作为最佳实践,也存在需要合理的/逻辑的情况。
根据是分别更改模型中的导航属性还是键属性,此问题可能通过以下异常表现出来:
发生了引用完整性约束冲突:当从属对象为Unchanged时,不能更改作为引用完整性约束一部分的主键属性,除非将其设置为关联的主对象。必须跟踪主体对象,并且不将其标记为删除。
属性“ X”是对象键信息的一部分,无法修改。
- 3 回答
- 0 关注
- 945 浏览
添加回答
举报