如何配置这种一对零或一对一的关系?

时间:2019-04-28 10:43:09

标签: c# ef-code-first entity-framework-core

我知道关于1:0..1-关系有一些已回答的问题。我看过thisthis,但认为它们不适用于我的问题。

我在CMS系统中拥有这三个(简化的)模型。

public class FrontPageItem
{
    public int Id { get; set; }
    public int ItemType { get; set; } // 1 = Article, 2 = WebPage, etc...

    public int? ArticleId { get; set; }
    public Article Article { get; set; }

    public int? WebPageId { get; set; }
    public WebPage WebPage { get; set; }
}

public class Article
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Preamble { get; set; }
    public string MainText { get; set; }

    public int? FrontPageItemId { get; set; }
    public FrontPageItem FrontPageItem { get; set; }
}

public class WebPage
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int? FrontPageItemId { get; set; }
    public FrontPageItem FrontPageItem { get; set; }
}

FrontPageItem与每种不同元素类型之间的关系是一对零或一个。元素可以存在而不必添加为FrontPageItem,这意味着FrontPageItem仅与一个元素(ArticleWebPage)有关系。

为了配置关系,我添加了以下代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Article>()
        .HasOne(p => p.FrontPageItem)
        .WithOne(i => i.Article)
        .HasForeignKey<FrontPageItem>(b => b.Id);
    modelBuilder.Entity<WebPage>()
        .HasOne(p => p.FrontPageItem)
        .WithOne(i => i.WebPage)
        .HasForeignKey<FrontPageItem>(b => b.Id);
}

但是我认为这是不正确的。我尚未制作FrontPageItem的CRUD视图,但是如果我尝试直接在VS的SQL Server对象资源管理器中添加项目,则必须输入PK的值。

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

如您所说:

  

FrontPageItem与每种不同元素类型之间的关系为one-to-zero-or-one。元素可以存在而不必添加为FrontPageItem,这意味着FrontPageItem仅与一个元素(ArticleWebPage)有关系。

然后从ArticleId中删除WebPageIdFrontPageItem作为EF核心支持one-to-one-or-zero关联,而原则表中没有外键:

public class FrontPageItem
{
    public int Id { get; set; }
    public int ItemType { get; set; } // 1 = Article, 2 = WebPage, etc...

    public Article Article { get; set; }
    public WebPage WebPage { get; set; }
}

然后为ArticleWebPage进行 Fleunt API 配置,如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Article>()
        .HasOne(a => a.FrontPageItem)
        .WithOne(f => f.Article)
        .HasForeignKey<Article>(a => a.FrontPageItemId); // <-- Here it is

    modelBuilder.Entity<WebPage>()
        .HasOne(wp => wp.FrontPageItem)
        .WithOne(f => f.WebPage)
        .HasForeignKey<WebPage>(wp => wp.FrontPageItemId); // <--Here it is
}