asp.net-mvc - 如何处理同一实体类型的多个一对零或一关系?
问题描述
据我了解,EF6 通过在相关实体上共享相同的 ID 实现一对零或一关系投影到数据库中
教程说:
当一个表的主键在关系数据库(如 SQL Server)中的另一个表中变为 PK 和 FK 时,就会发生一对零或一关系。因此,我们需要以这样的方式配置上述实体,即EF在DB中创建Students和StudentAddresses表,并将Student表中的StudentId列作为PrimaryKey(PK),将StudentAddresses表中的StudentAddressId列作为PK和ForeignKey(FK ) 两个都。
所以如果 aWebsite
有一个 optional WebsitePage
,我可能会有这个:
public class Website
{
public int Id { get; set; }
public virtual WebsitePage Page { get; set; }
}
public class WebsitePage
{
[Key, ForeignKey( nameof( Website ) )]
public int Id { get; set; }
public virtual Website Website { get; set; }
}
但是如果我想要多个可选页面,像这样呢?
public class Website
{
public int Id { get; set; }
public virtual WebsitePage AboutPage { get; set; }
public virtual WebsitePage ServicesPage { get; set; }
public virtual WebsitePage CaseStudyPage { get; set; }
}
public class WebsitePage
{
[Key, ForeignKey( nameof( Website ) )]
public int Id { get; set; }
public virtual Website Website { get; set; }
}
可能是我今天的谷歌搜索不合格,但我无法在网上或在 SO 上找到任何此类示例。
我错过了什么,还是我的理解有缺陷?
解决方案
最初我误解了你想要实现的关系的标题。当我们在另一个模型中有多个引用时,无法完成一对零或一关系。你要求的是一对多的关系;一方面,我们有 1 个WebsitePage
对象,另一方面,我们有n
相关的Website
对象,可以有 1-3WebsitePage
秒(请参阅评论)。为此,您可以使用Nullable Foreign Keys。在导航属性旁边提供可为空的 ID 属性:
public class Website
{
[Key]
public int Id { get; set; }
public int? AboutPageId { get; set; }
public virtual WebsitePage AboutPage { get; set; }
public int? ServicesPageId { get; set; }
public virtual WebsitePage ServicesPage { get; set; }
public int? CaseStudyPageId { get; set; }
public virtual WebsitePage CaseStudyPage { get; set; }
}
public class WebsitePage
{
[Key]
public int Id { get; set; }
}
WebsiteId
在WebsitePage
模型中是没有必要的。请参阅EF6 内置约定。
您也可以使用 Fluent API,就像他们在您链接的教程中所做的那样。
编辑:如果您希望每个页面仅属于一个网站,您可能需要分离模型并使用中间模型:
public class Website
{
[Key]
public int Id { get; set; }
public virtual IList<WebsitePage> WebsitePages { get; set; }
}
public class Page
{
[Key]
public int Id { get; set; }
//public PageType Type { get; set; }
public virtual IList<WebsitePage> WebsitePages { get; set; }
}
public class WebsitePage
{
[Key, ForeignKey(nameof(Page))]
public int PageId { get; set; }
public virtual Page Page { get; set; }
public int WebsiteId { get; set; }
public virtual Website Website { get; set; }
}
PageId
不能重复,每条记录都需要一个WebsiteId
; 每个页面将只属于一个网站(如果有)。它使用 .NET Core 3.1/EF Core 2.2 进行了测试。
同样,您可能只能使用两个模型 (Website
和Page
) 和 Fluent API 来指定它们之间的多对多关系必须如何防止重复。
推荐阅读
- google-cloud-platform - 谷歌云存储更改存储类而不重写
- angular - 访问 Angular 中的全局变量(`LC_API`)
- ios - 防止发布更新后删除数据
- css - reactjs如何在sidedrawer中添加动画
- python - 将参数传递给 cursor.execute() 时,pyodbc 中的 UnicodeDecodeError,但在将参数直接写入字符串时没有
- sql-server - MS Flow:SQL Server Get_rows - 我们无法将运算符 < 应用于 DateTimeZone 和 DateTime 类型
- ruby-on-rails - Rails:为什么这个连接查询失败了?
- arrays - x86 程序集任务中超出范围的数组元素的内容
- apache - Gremlin 重复直到在 path() 上返回边缘
- c++ - C++异常处理内部循环不起作用