如何让EF6遵守关联/关系多重性中的唯一约束(在FK上)?

15

2019更新 / TLDR; 切换到Entity Framework Core(或其他)

尽管缺少一些“功能”,EF Core除了主键外,正确使用替代键(又称唯一约束条件),因此在遵循关系代数方面做得更好。否则,则可能会因情况而异;至少它正确支持许多SQL架构。

此支持已添加到(非常过时的)EF Core 1.0发布版中。有点令人失望的是,原始EF从未解决这个设计(约束!)缺陷。


这可能与我的其他问题有关 - 看起来要么是:

  1. Entity Framework是一个可怕的关系代数映射器1或;

  2. (我希望如此)我忽略了SSDL / CSDL和EDMX模型或EF映射中的某些内容。

我有一个基于Schema的模型,模式看起来像这样:

ExternalMaps
---
emap_id - PK

Melds
---
meld_id - PK
emap_id - >>UNIQUE INDEX<< over not-null column, FK to ExternalMaps.emap_id

为了验证,这些脚本应该被编写成以下形式,这将导致多个ExternalMaps: 1 < - > 0..1:Melds2

ALTER TABLE [dbo].[Melds] WITH CHECK ADD CONSTRAINT [FK_Melds_ExternalMaps]
FOREIGN KEY([emap_id]) REFERENCES [dbo].[ExternalMaps] ([emap_id])

CREATE UNIQUE NONCLUSTERED INDEX [IX_Melds] ON [dbo].[Melds] ([emap_id] ASC)

然而,当我使用EDMX设计器从头开始更新数据库(SQL Server 2012)时,它会错误地将关联/外键关系创建为ExternalMap:1 <-> M:Meld

当我尝试手动更改Meld的多重性(通过设计器中的“关联集”属性)为10..1时,我得到以下信息:

 

运行转换:在关系“FK_Melds_ExternalMaps”的“Meld”角色中,多重性无效。因为从属角色属性不是关键属性,所以从属角色的上限多重性必须为*

(与我的其他问题一样,这似乎与唯一约束条件被正确注册/视为候选键有关。)

我该如何让EF遵守模型建立的1 <-> 0..1/1多重性关系?


1虽然我希望情况不是这样,但是当我试图将EF映射到一个完全有效的RA模型时,我遇到了很多问题:LINQ to SQL(L2S)却没有这个问题。由于我的另一个问题在这样一个受欢迎的ORM中没有得到简单回答,我对这个工具失去了信心。

2外键不是双向的设计方式:“你不应该有可空外键。” - 它也不是共享的PK,就像2009年的答案所提出的那样。

我使用EF 6.1.1,VS 2013 Ultimate,并且不会使用任何“OO子类型功能” - 如果有任何更改,请告诉我。


编辑叹气

从属角色属性不是关键属性,因此多重性无效?(来自2011) - 在2015年,“微软认可的企业级”ORM EF中是否仍然存在此问题?

如果继续这样下去,下一次有人问为什么没有使用EF,我将有很多理由,而不仅仅是“LINQ to SQL完全正常”..


当您移除唯一性约束时,它是否会为您生成正确的数据库/模型? - Youp Bernoulli
2
EF从未支持过这个功能。EF仅支持共享主键上的1:1或1:0..1。虽然有关于修复此问题的讨论,它可能会在EF7中得到解决,但目前为止还不支持(这里有一些关于此问题的问题)。L2S也不支持此功能,尽管它似乎对您有效。不能保证其可行性,因此您可能会发现您的代码在某一天无法正常工作。如果您正在进行新的EF开发,则也不应使用EDMX,因为EDMX文件将在EF7中消失。 - Erik Funkenbusch
@ErikFunkenbusch 感谢您提供的信息。我希望ES6文档/赞美指南在这方面能更清晰明了。EF7中将用什么替代EDMX以支持基于模式的开发?无论如何,L2S似乎确实支持这种情况——至少在codeplex上的TT插件中是如此。(而且我从未遇到过它“不起作用”的情况。) - user2864740
就像我之前所说的,它可能“能用”,但它并没有得到官方支持。L2S是比EF更简单的系统,因此您通常可以做一些EF不允许的事情,因为它具有更多的验证。EF7仍将支持模型和数据库优先,但它将生成代码模型而不是EDMX文件。 - Erik Funkenbusch
顺便说一下,EF不支持这个的原因并不是因为它是一个差劲的映射器,而是因为在EF6.1之前它没有任何机制来支持唯一约束。由于没有本地SQL概念的1:1,它只能通过具有唯一约束的1:M来模拟,而EF不支持这种情况。EF 6.1添加了唯一索引,但不幸的是,内部逻辑基本上没有改变,并且正在验证它不能这样做,因为它还没有更新。为什么它不支持约束?因为这个功能从未成为优先事项的一部分。 - Erik Funkenbusch
显示剩余17条评论
1个回答

19
问题在于Entity Framework(从EF4到EF6.1,以及之后不知道还要多久)不“理解”唯一约束的概念及其所涵盖的所有内容:EF映射Code First,而不是关系代数 *叹气* 这个答案针对我的相关问题提供了一个链接到请求添加缺失功能并总结了如下信息:

.. Entity Framework当前仅支持基于主键构建引用约束,并没有独特约束的概念

这可以扩展到几乎所有涉及唯一约束和候选键的领域,包括此问题中提出的多重性问题。
我会很高兴如果EF的这个严重限制能被公开讨论并“广为人知”,特别是当EF被吹捧支持Schema First和/或替代L2S时。在我看来,EF只集中于映射(并支持)Code First作为一流公民。也许还需要等上四年..

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接