我有下表:
CREATE TABLE [dbo].[Exception] (
[ExceptionID] INT IDENTITY (1, 1) NOT NULL,
[ParentExceptionID] INT NULL,
[ApplicationID] INT NOT NULL,
[TypeName] VARCHAR (256) NOT NULL,
[Message] VARCHAR (MAX) NULL,
[StackTrace] VARCHAR (MAX) NULL,
[MachineName] VARCHAR (128) NULL,
[UserName] VARCHAR (64) NULL,
[CreatedOn] DATETIME NOT NULL
)
这用于存储应用程序中发生的异常。我有一个外键:
ALTER TABLE [dbo].[Exception] ADD CONSTRAINT [FK_ParentException_Exception]
FOREIGN KEY ([ParentExceptionID])
REFERENCES [dbo].[Exception] ([ExceptionID])
ON DELETE NO ACTION ON UPDATE NO ACTION;
为什么我将它设计为ParentExceptionID而不是InnerExceptionID,我无法告诉你。这肯定会让它在E.F.中显得格外混乱。但这完全是随意的,因为你可以用任何方式表达相同的数据。
正如您应该知道的,Exception只能有一个内部异常。但是,此架构允许多行声明具有相同的ParentExceptionID。从逻辑上讲,这种情况从未发生过,但数据支持它。
通常,当我想在模式中建立非递归的一对一关系时,我要么在两个表中使用相同的主键列名,要么在第二个表的外键中添加唯一索引。
前者看起来像这样:
Table A
PrimaryKey int
[...]
Table B
PrimaryKey int
[...]
或者另一种方式:
Table A
PrimaryKeyA int
[...]
Table B
PrimaryKeyB int
PrimaryKeyA int unique references A.PrimaryKeyA
[...]
在任何一种情况下,SQL图表和其他工具都会将此视为一对一的关系。实体框架只识别第一种模式,但我读过。
我的问题是,使用递归外键,我不能使用任何一种模式。我显然不能拥有第一个模式,因为我只有一个表。我不能使用第二个,因为我不能在外键列上有唯一索引,因为有多个行具有NULL ParentExceptionID。伙计,我希望SQL Server允许一个不强制NULL的唯一索引也是唯一的!
当我尝试从此模式制作E.F.模型时,它会发现多行可以声称具有相同的ParentExceptionID,并且它强制我将其建模为0..1 -> *
。我看不出任何阻止这种情况的方法。 My Exception实体有一个InnerException导航属性,它是一个集合。显然,这不是我需要的。如果我尝试更改关联的多样性并强制它为0..1我得到一个构建错误:
多重性在关系'FK_ParentException_Exception'中的角色'InnerException'中无效。由于Dependent Role属性不是关键属性,因此Dependent Role的多重性的上限必须为*。
有什么办法可以做我想要的吗?即使这意味着改变我的架构,我也可以考虑一下。现在我觉得这是不可能的。
答案 0 :(得分:0)
没有办法在EF中映射它,甚至外键上的Unique索引也无济于事,因为当前版本的EF不支持唯一键。
唯一的方法是将其映射为一对多并隐藏真实的导航属性,例如内部成员。而不是你将在实体类的部分部分中暴露另一个属性(不在实体图中),这将允许仅定义单个内部异常(它将仅使用内部集合中的第一个项)。
此解决方案的问题部分是急切加载相关异常,因为您无法加载自定义属性,只能加载导航属性。