9

我遇到了一个场景,其中实体框架4.0不会生成一个关联到由具有唯一索引的表支持的实体,我想知道为什么。EF 4为什么不生成与具有唯一索引的列的FK关系的关联?

基本设置是这样的:比方说,我在SQL Server 2008 R2和外键关系的两个表:

CREATE TABLE [dbo].[User](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [GroupId] [int] NULL, 
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

CREATE TABLE [dbo].[Group](
[Id] [int] IDENTITY(1,1) NOT NULL, 
CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

ALTER TABLE [dbo].[User] WITH CHECK ADD CONSTRAINT [FK_User_Group] 
    FOREIGN KEY([GroupId]) 
REFERENCES [dbo].[Group] ([Id]) 

此外,假设以下索引存在:

CREATE NONCLUSTERED INDEX [IX_Group] ON [dbo].[Group] 
(
[Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

如果我告诉Visual Studio 2010中的设计器生成一个ADO.NET实体数据模型,我将得到一个带有两个类的模型UserGroupUser,该模型具有一个名为Group的导航属性。这一切都很好。

现在,让我们说不是,该指数是这样的:

CREATE UNIQUE NONCLUSTERED INDEX [IX_Group] ON [dbo].[Group] 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

也就是说,只有事情我所做的是使索引唯一索引。完成此操作后,当我告诉Visual Studio的设计人员生成实体模型时,用户和组之间的关联不显示,并且User没有导航属性。检查生成的EDMX文件显示存储模型根本没有AssociationSet。

任何人都可以解释为什么这是?为什么唯一索引阻止EF建模关系?

谢谢。

回答

12

唯一索引允许1个NULL值,主键不允许NULLS。当没有任何东西等于NULL时,你将如何匹配NULL甚至没有另一个NULL

+0

嗯,也许你是对的,但Linq2SQL可以处理这种情况。另外,我可以手动在EDMX中添加适当的AssociationSets等,它会正常工作,所以我仍然不明白EF放弃的原因。 – Rune 2010-08-19 08:26:33

+0

thnaks人很多,我浪费了1个多小时调查为什么导航属性不映射,你的答案帮助我。再次感谢 – 2014-01-28 09:54:10

1

我有同样的问题。但是,就我而言,我试图链接到的列不是主键。因此,它不会工作。 EDMX文件不会编译,说它必须链接到主键。这是有道理的。我遇到这个问题的唯一原因是我正在处理设计不佳的遗留数据库。

但是,就你而言,你正在创建一个唯一的标识列索引。为什么?无论如何,身份列保证是唯一的。此外,它是你的主键,默认情况下它会有一个索引。

我发现这个链接解释了EF中目前不支持与唯一约束的关联,但是,它看起来像他们正在为将来的发行版计划它。

http://blogs.msdn.com/b/efdesign/archive/2011/03/09/unique-constraints-in-the-entity-framework.aspx?wa=wsignin1.0&CommentPosted=true#commentmessage

+0

“为什么?无论如何,身份列保证是唯一的。”不,它不是。 “SET IDENTITY_INSERT”或“DBCC RESEED”可能有重复的值。 – hvd 2012-02-25 18:25:29

+0

呃,是的,但是,你必须竭尽全力去做到这一点。当你这样做的时候,这是故意的。 – 2012-05-05 18:13:54

+0

我回应说:“无论如何,一个身份列保证是唯一的。“这意味着你不可能得到重复的价值观,但是你现在说的你的真正意思是不可能无意中得到重复的价值。这可能是事实(我不完全确定),但是它的要求太差了,如果多个应用程序在同一个数据库上工作,这意味着假设该列是唯一的可能是无效的,因为另一个应用程序上的另一个用户可能有意插入了一个您不期望的重复值。 – hvd 2012-05-05 21:59:05

相关问题