【问题标题】:EF Code First Self-Referencing Composite KeyEF Code First 自引用复合键
【发布时间】:2017-12-11 21:38:11
【问题描述】:

我正在制作一个 EF 代码优先的 MVC 模型来存储文章。

每篇文章可以有多个页面,所以我将键设置为 ID 加页码的组合键。

我还希望文章有子文章,所以我希望文章使用外键自引用。

由于键是复合键,我正在努力解决自引用问题。当我搭建模型并尝试使用控件时,我得到“System.StackOverflowException”

public class Article
    {

        [Key, Column(Order = 0)]
        public int ArticleID { get; set; }

        [Key, Column(Order = 1)]
        public int ArticlePageNo { get; set; }

        public string ArticleTitle { get; set; }

        public string ArticleBody { get; set; }

        [ForeignKey("ArticleID, ArticlePageNo")]
        public Article ArticleParent { get; set; }
    }

【问题讨论】:

  • 为什么有一个引用自身的复合键?你能把一篇文章和它的页面分开存储吗?还是文章本身也需要引用?
  • 我希望文章具有父文章和子文章,因此需要自引用。我还想要使用复合键的分页文章。这就是为什么我需要一个引用自身的复合键。
  • 如果不能以这种方式工作,我会考虑单独存储页面。

标签: c# asp.net-mvc code-first


【解决方案1】:

在这种情况下,我确实认为您没有正确使用 EF。 如果我正确理解您的代码,EF 将尝试将对象引用到自身,如果您使用的是急切加载方案,则会导致 Stackoverflow 异常。因此,您实际上是在 Article 和 Article 之间定义 1 对 1 的关系,将主键和外键都指定为由 ArticleID 和 ArticlePageNo 形成的复合键。不是 EF 可以消化的东西。 我建议你重塑你的数据:所以你有文章和页面之间的一对多关系,以及文章和文章之间的一对多关系。代码看起来像这样:

public class Article
{
    // object unique ID
    public int Id { get; set; }
    public string Title { get; set; }

    // parent Id used as foreign key
    public int? ParentArticleId { get; set; }
    // navigational property for parent
    public virtual Article ParentArticle { get; set; }
    // navigational property for children
    public virtual ICollection<Article> Articles { get; set; }
    // navigational property for article pages
    public virtual ICollection<ArticlePage> Pages { get; set; }
}

public class ArticlePage 
{
    // object unique ID
    public int Id { get; set; }
    public string PageBody { get; set; }

    // parent Id used as foreign key
    public int ArticleId { get; set; }
    // navigational property for parent article
    public virtual Article { get; set; }
}

【讨论】:

    【解决方案2】:

    这个模型实现了我试图做的事情,但根据反馈我可能会重新考虑我的方法。

    public class Article
    {
    
        [Key, Column(Order = 0)]
        public int ArticleID { get; set; }
    
        [Key, Column(Order = 1)]
        public int ArticlePageNo { get; set; }
    
        public string ArticleTitle { get; set; }
    
        public string ArticleBody { get; set; }
    
        public int? ParentArticleID { get; set; }
        public int? ParentArticlePageNo { get; set; }
    
        [ForeignKey("ParentArticleID,ParentArticlePageNo")]
        public virtual Article ArticleParent { get; set; }
    
        public virtual ICollection<Article> Articles { get; set; }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多