在Entity Framework 4中,可以将递归外键建模为一对一吗?

时间:2011-04-22 00:25:24

标签: sql-server-2005 entity-framework-4 mapping entity-relationship

我有下表:

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的多重性的上限必须为*。

有什么办法可以做我想要的吗?即使这意味着改变我的架构,我也可以考虑一下。现在我觉得这是不可能的。

1 个答案:

答案 0 :(得分:0)

没有办法在EF中映射它,甚至外键上的Unique索引也无济于事,因为当前版本的EF不支持唯一键。

唯一的方法是将其映射为一对多并隐藏真实的导航属性,例如内部成员。而不是你将在实体类的部分部分中暴露另一个属性(不在实体图中),这将允许仅定义单个内部异常(它将仅使用内部集合中的第一个项)。

此解决方案的问题部分是急切加载相关异常,因为您无法加载自定义属性,只能加载导航属性。