Entity Framework Core 2.0(问题提出时的最新版本)没有这样的机制,但是EF Core 2.2可能会有 - 以Owned Entity Types的形式。
因为你说:
"我只从People
行开始并搜索Addresses
记录;我从不找到一个Addresses
行"
那么,您可能希望将Address
作为Owned Entity Type(尤其是使用'在单独的表中存储所拥有类型'的变体,以匹配您选择将地址信息存储在单独的Addresses
表中)。该功能的文档似乎说了一句匹配的话:
"所拥有的实体基本上是所有者的一部分,不能没有它而存在"
顺便说一下,现在该特性已经在 EF 中,这可能可以解释为什么 EF 总是为
HasMany
/
HasOne
创建索引。这很可能是因为
Has*
关系应该用于其他实体(而不是“值对象”),由于它们具有自己的标识,因此意味着可以独立查询它们,并使用导航属性访问它们相关联的其他实体。但对于这种用例来说,如果没有索引,使用这些导航属性将非常危险(少数查询可能会导致数据库大幅减速)。
然而,在这里有一些要注意的地方:
将一个实体转换为拥有的实体并不仅仅是指示 EF 关于索引的事项,而是指示以一种略微不同的方式将模型映射到数据库中(有关详细信息,请参见下文),但最终效果实际上不包含在
People
上的额外索引。
但很有可能,这实际上可能是更好的解决方案:这样你也可以说没有人应该查询地址(通过
不允许创建那种类型的DbSet<T>
),从而最大程度地减少了有人使用它来访问其他实体的机会,以及这些昂贵的无索引查询。
关于它们的区别,你会注意到如果你让
Address
属于
Person
,EF会在
Address
表中创建一个
PersonId
列,这与
People
表中的
AddressId
不同(从某种意义上说,缺少外键有点欺骗性:查询地址的人的索引是存在的,只是它是
People
表的主键索引,本来就存在)。但请注意,这个设计实际上相当好——它不仅需要少一列(
People
中没有
AddressId
),而且还保证了没有办法制作孤立的
Address
记录,你的代码永远无法访问。
如果你仍然想在
Addresses
中保留
AddressId
列,那么还有一个选项:
- 在
Addresses
表中为外键选择一个名称AddressId
,并且“假装”你不知道它恰好具有与PersonId
相同的值 :)
如果这个选项不好玩(例如因为您无法更改数据库模式),那么您可能会有些倒霉。但请注意,在EF的当前缺点中,他们仍然列出了“拥有实体类型的实例不能由多个所有者共享”,而以前版本的一些缺点已经被列为已解决。也许值得关注这个领域,因为在我看来,解决这个问题可能涉及到在People
中拥有您的AddressId
的能力,因为在这样的模型中,为了使拥有的对象在多个实体之间共享,外键需要与拥有实体一起放置,以为每个实体创建对相同值的关联。
db.Database.EnsureCreated();
从头开始创建数据库。据我所知,索引的创建是在幕后自动完成的。顺便说一下,这是 EF Core 2。 - pbristow