【问题标题】:Working with a Model class that has a foreign/navigation key to itself使用具有外部/导航键的模型类
【发布时间】:2011-10-02 13:01:02
【问题描述】:

我正在尝试在 ASP.NET MVC 3 中开发一个目录项目,并首先将 EF 代码与现有数据库一起使用。我的数据库中有一个 Categories 表指向它自己。为此,我编写了以下模型类。 --“如果模型错误,请纠正我”--

public class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public int? ParentCategoryID { get; set; }
    public string CategoryDesc { get; set; }

    [ForeignKey("ParentCategoryID")]
    public virtual Category ParentCategory { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

问题:我无法理解如何使用这门课。在使用以下代码并将其传递给视图时

var cat = dbStore.Categories.Include("ParentCategory").ToList()

我收到此错误:对象引用未设置为对象的实例。发生这种情况是因为根类别的 ParentCategoryID 为空。请告诉我您将如何使用此代码或任何可以帮助我理解在这种情况下工作的资源。使用上述模型的任何类型的代码都会有所帮助,例如显示列表或菜单或任何东西,任何东西。

【问题讨论】:

    标签: entity-framework-4.1 ef-code-first entity-relationship code-first hierarchical-data


    【解决方案1】:

    通常,您所做的就是从顶级类别转到底层类别。为此,您首先需要在您的类中定义 SubCategories 集合

    public class Category
    {
        public int CategoryID { get; set; }
        public string CategoryName { get; set; }
        public int? ParentCategoryID { get; set; }
        public string CategoryDesc { get; set; }
    
        [ForeignKey("ParentCategoryID")]
        public virtual Category ParentCategory { get; set; }
    
        [InverseProperty("ParentCategory")]
        public virtual ICollection<Category> SubCategories{ get; set; }
    
        public virtual ICollection<Product> Products { get; set; }
    }
    

    然后你检索顶级类别

    var topCategories = dbStore.Categories
       .Where(category => category.ParentCategoryID == null)
       .Include(category => category.SubCategories).ToList();
    

    之后你可以遍历层次结构

    foreach(var topCategory in topCategories)
    {
        //use top category
        foreach(var subCategory in topCategory.SubCategories)
        {
    
        }
    
    }
    

    【讨论】:

    • 是否需要添加 InverseProperty 才能处理这种类型的分层数据? .这种类型的利用是否适用于所有类型的场景,例如菜单、列表、产品列表以及处理类别的每个需求。
    • @Pankaj 它不仅适用于分层数据。如果 EF 无法通过约定找出关系,那么我们必须通过属性或 fluent API 显式配置它们。
    • 我试过这段代码,它工作正常;但这只是一个深层次。深层嵌套类别从列表中排除。像 :: category--subCategory--subsubCategory。在此 subsubCategory 中被排除。我需要包含与嵌套类别一样多的逆属性吗?
    • @Pankaj 你可以随心所欲,例如:Include(category =&gt; category.SubCategories.Select(sc =&gt; sc.SubCategories))
    • 谢谢哥们。但是这样一来,我总是需要确定数据的深度,对吧??。如果有人深入到第 5 类呢?难道不能有一种动态的方式来处理这种情况吗?
    【解决方案2】:

    如果您没有太多类别,您可以通过加载整个类别集合来解决此问题。我认为 EF 会为您处理修复,以便正确填充所有关系。

    据我所知,没有 SQL'ish 数据库/ORM 可以很好地处理这种情况。我经常使用的一种方法是如上所述加载整个集合,然后手动修复关系。但我确实认为 EF 会为你做到这一点。

    基本上你应该这样做:

    var topCategories = dbStore.Categories.ToList().Where(category => category.ParentCategoryID == null);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-03
      • 2018-06-02
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      相关资源
      最近更新 更多