【问题标题】:Tree node design in Entity Framework Code FirstEntity Framework Code First 中的树节点设计
【发布时间】:2011-06-11 07:38:58
【问题描述】:

我想设计一个基础树节点类,其他实体类可以从中派生,我想应该是这样的:

public abstract class BaseTreeNode
{
  public string Id{get;set;}

  public string Name{get;set;}

  public string ParentId{get;set;}

  [ForeignKey("ParentId")]
  public BaseTreeNode ParentNode{get;set;}
}

public class MenuNode:BaseTreeNode
{

}

但是,当尝试使用 MenuNode 类构建一些层次结构时,它似乎不起作用。当我调用 SaveChanges 方法时,它抛出了 SqlException:Invalid object name 'dbo.BaseTreeNode'。

我认为问题在于属性“ParentNode”,因为它是一个抽象类。 那么,在这种情况下,我应该如何首先使用实体​​框架 4.1 代码来设计我的类。

非常感谢!

【问题讨论】:

  • 我认为问题不在于ParentNode 属性。该模型是有效的(PrarentId 除外,我猜这只是一个错字)。问题一定出在其他地方。您能否展示 1) 带有 DbSet 属性的 DbContext,2) 任何 Fluent 映射(如果有的话),3) 引发异常的代码。

标签: tree entity-framework-4.1 ef-code-first


【解决方案1】:

这种方法的问题在于性能。您可能希望在 DB 中存储多种类型的树(Menu/SubMenu、Category/Subcategory),但是这种类型的继承会导致它们一起存储在一个表中。看到这个问题:What are the pros and cons of one master base table which all entities inherit from?

问题是是否有必要查询所有类型的节点,而不考虑树的类型。

【讨论】:

  • 其实我认为你错了 Loren,EF 会为每个派生类型生成一个表,所以他应该在数据库中创建一个名为 MenuNode 的表以及他创建的其他节点类型,基本类型是有效的仅在 c# 上下文中使用以允许 clr 构建完整的对象
  • 不,我只是试了一下。默认行为是 table-per-hierarchy 继承,这意味着所有子类都存储在一个表中,并使用一个 discriminator 列来区分子类。在本例中,生成的表名为 BaseTreeNodes,鉴别器列定义为“[Discriminator] [nvarchar](128) NOT NULL”
  • 多么奇特......我最近用 EF 代码编写了一个基本的文档管理系统,首先在我的 C# 代码中采用了这种方法。我最终得到了 3 个类(FileSystemObject、Directory、File),后 2 个继承了第一个类,我在 db 中得到了 2 个表(Directories、Files)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2014-12-29
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-11
相关资源
最近更新 更多