asp.net-mvc - 实现同一类的一对零或一关系和一对多关系
问题描述
我在映射以下类时遇到问题。
我想MainAboutPage
成为可选的(一对零或一)并且AboutSubPages
显然是一对多的。
理想情况下,我想将WebsiteId
属性保留在WebsitePage
课堂上。
public class Website
{
public int Id { get; set; }
public virtual WebsitePage MainAboutPage { get; set; }
public ICollection<WebsitePage> AboutSubPages { get; set; }
}
public class WebsitePage
{
public int Id { get; set; }
public int WebsiteId { get; set; }
public virtual Website Website { get; set; }
}
当我不使用流利的映射时,我得到
无法确定关系的主体端。多个添加的实体可能具有相同的主键。
当我使用这个流畅的映射时:
modelBuilder.Entity<Wesbite>()
.HasMany(x => x.AboutSubPages)
.WithRequired(x => x.Website)
.HasForeignKey(x => x.WebsiteId);
我得到:
无法确定“Wesbite_AboutSubPages”关系的主体端。多个添加的实体可能具有相同的主键。
当我使用这个流畅的映射时:
modelBuilder.Entity<Website>()
.HasOptional(x => x.MainAboutPage)
.WithRequired();
modelBuilder.Entity<Wesbite>()
.HasMany(x => x.AboutSubPages)
.WithRequired(x => x.Website)
.HasForeignKey(x => x.WebsiteId);
我得到:
无法确定“Website_MainAboutPage”关系的主体端。多个添加的实体可能具有相同的主键。
当我使用这个流畅的映射时:
modelBuilder.Entity<Website>()
.HasOptional(x => x.MainAboutPage)
.WithRequired(x => x.Website);
modelBuilder.Entity<Wesbite>()
.HasMany(x => x.AboutSubPages)
.WithRequired(x => x.Website)
.HasForeignKey(x => x.WebsiteId);
我得到:
Wesbite_MainAboutPage_Target::多重性在关系“Website_MainAboutPage”中的角色“Wesbite_MainAboutPage_Target”中无效。因为从属角色属性不是关键属性,所以从属角色的多重性的上限必须是“*”。
我一直在无休止地阅读 MS 的配置示例:https ://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx和https://www.entityframeworktutorial .net/code-first/configure-one-to-many-relationship-in-code-first.aspx
我的大脑被腌制了,如果我遗漏了一些明显的东西,请原谅我。我真的很感激一些关于我想要的设置的指示。
提前致谢。
解决方案
我相信问题在于您没有足够的信息让 EF 区分关于网站的 AboutSubPages 和 MainAboutPage 引用。要在网站上为 MainAboutPage 建立 1..0/1 关系,您需要在网站表中声明 MainAboutPageId。
modelBuilder.Entity<Website>()
.HasOptional(x => x.MainAboutPage)
.WithRequired(x => x.Website)
.HasForeignKey(x => x.MainAboutPageId);
或者,您可以选择使用影子属性 (EF Core) 或Map.MapKey
(EF6) 来映射关系,而无需在实体中公开 FK。(推荐的)
具有 1..0/1 加上 1..many 与相同相关实体的实体关系的警告是,无法强制 MainAboutPage 实际上属于子集合。因为 1..0/1 依赖于从网页到子页面的 FK,所以没有强制要求子页面必须指向同一个网站。EF 和 Database 非常乐意让 WebSite ID #1 指向具有 WebSite ID #2 的子页面。
更好的方法可能是只查看维护 AboutSubPages 集合并将 PageOrder 数字唯一索引添加到 SubPage 实体。例如,“主”子页面将是具有最低 PageOrder 的页面。
即选择一个网站的详细信息,它是关于页面的“主要”:
var websites = context.Websites
.Select(x => new WebsiteSummaryViewModel
{
Name = x.Name,
AboutPageURL = x.AboutSubPages
.OrderBy(a => a.PageOrder)
.Select(a => a.Url)
.FirstOrDefault()
}).ToList();
... 举个例子。这确保了我们可以访问主页,同时确保网站考虑的唯一页面是分配给它的页面。可以在网站实体上设置未映射的属性以从嵌入式集合中返回“MainAboutPage”,但是我不建议使用未映射的属性,因为它们很容易滑入 Linq 表达式,并且 EF 将抛出异常或执行过早执行(EF Core)来解决这些问题。
推荐阅读
- angular - 无法在角度 7 中执行另一个组件的方法
- ms-word - 隐藏后台按钮
- html - 如何修复 MaterializeCSS 垂直对齐
- apache-spark - 将 Spark 作业从 Windows 机器提交到远程纱线集群(Unix)
- javascript - Document.body.removeChild() 仅在调试模式下删除模式
- logging - 在 JBoss 7 中使用 Filter-spec 从堆栈跟踪日志中过滤中间件帧
- ios - 用户从打开的网址返回后如何防止屏幕重建
- docker - 使用音量时如何排除子文件夹?
- javascript - 具有超链接的图像地图工具提示在 Internet Explorer 版本 11 中不起作用
- android - 如何在 RecyclerView 适配器中显示材质对话框?