Post.FbPost为null或FbPost,并且没有两个Post实体可以引用相同的FbPost实体.换句话说,零或一对一.
在sql Server中(理想情况下)将此实现为零或一对一而不是多对一的正确方法是什么?
如果那是不可能的,我该如何在EF级别强制执行此操作?
解决方法
它可以为空的事实意味着您可以在源表中有一个空条目,该条目不引用目标表中的条目.并且,如果它不为null,则唯一约束确保源表中只有一行可以引用目标表中的行.
不幸的是,至少在sql Server(a)中,唯一约束列中的NULL也必须是唯一的,尽管这会“破坏”sql指南,即NULL不等于任何值,包括另一个NULL.所以基本上,这种方法不适用于sql Server.
摆脱这个窘境(b)的一种可能方法是具有可空列的外键约束,但没有唯一约束.这将允许您确保您根本不引用目标表中的行(源表中的NULL)或引用目标行(源表中的任何非NULL值).
但是,它不会为您提供“只有一个源行可以引用目标行”的要求.这可以添加一个before-(插入/更新)触发器,该触发器将检查源表中的每隔一行以确保没有其他行已经引用目标行.
而且你几乎总是喜欢数据库本身的约束.您永远不知道恶意应用程序(恶意或错误)何时连接到您的数据库并决定不遵守规则.
(a)从here开始的以下文本显示了对几个DBMS产品中可为空的唯一列的不同支持:
标准:
如约束名称所示,具有UNIQUE约束的(一组)列可能仅包含唯一(组合)值.
除非DBMS实现可选的“允许NULL”功能(功能ID 591),否则受UNIQUE约束约束的列或一组列也必须遵循NOT NULL约束.可选功能为UNIQUE约束添加了一些额外的特性:
首先,UNIQUE约束中涉及的列也可能具有NOT NULL约束,但它们不必具有.其次,如果具有UNIQUE约束的列也不具有NOT NULL约束,则列可以包含任意数量的NULL’值'(NULL不等于NULL的逻辑结果).
Postgresql的:
DB2:
遵循UNIQUE约束的非可选部分.不实现可选的NULL允许功能.
MSsql:
跟随标准扭曲.
MSsql提供允许NULL的功能,但如果允许NULL,则允许最多一个NULL’值’实例.换句话说,它破坏了标准的上述描述中的特征2.
MysqL的:
甲骨文:
遵循有关多列UNIQUE约束的标准.
实现了可选的NULL允许功能:如果对单个列施加UNIQUE约束,则该列可以包含任意数量的NULL(如上面标准描述中的特征2所预期的那样).但是,如果为多个列指定了UNIQUE约束,那么Oracle会将约束视为违反任何两行
>在受约束影响的列中包含至少一个NULL
>受约束影响的其余列中的相同非NULL值
(b)另一种方法当然是选择实现此功能的DBMS,如Postgresql或MysqL.
在您的具体情况下,这可能是不可能的,但至少应考虑到它.例如,我避开Oracle,因为它无法从某些字符列中的空字符串中辨别NULL,尽管其他人可能不像我那样“纯粹主义”(我的妻子会说“肛门保持”):-)