2011-06-11 63 views
0

我想设计一个基地树节点类从其他实体类可以得到,我认为这将是这样的:树节点设计首先

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:无效的对象名'dbo.BaseTreeNode'。

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

非常感谢!

+0

有人能帮助我吗? – NicolasZ 2011-06-12 05:13:31

+0

我不认为问题是'ParentNode'属性。该模型是有效的(除了'PrarentId',我猜只是一个错字)。问题一定在其他地方。你可以显示1)你的DbContext的DbSet属性,2)任何Fluent映射,如果你有一个,3)抛出异常的代码。 – Slauma 2011-06-12 17:57:10

回答

0

这种方法的问题将是性能。您可能需要在数据库(Menu/SubMenu,Category/Subcategory)中存储多种类型的树,但是这种类型的继承将导致所有这些树一起存储在一个表中。看到这个问题:What are the pros and cons of one master base table which all entities inherit from?

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

+0

其实我认为你错了Loren,EF会为每个派生类型生成一个表,所以他应该在db中创建一个名为MenuNode的表,并且创建其他节点类型,基类型实际上只在ac#上下文中用于允许clr构建一个完整的对象 – War 2012-08-01 17:36:18

+0

不,我只是试了一下。默认行为是每层继承,这意味着所有子类都存储在一个表中,并使用鉴别器列来区分子类。在这个例子中,结果表被命名为BaseTreeNodes,并且鉴别器列被定义为“[Discriminator] [nvarchar](128)NOT NULL” – 2012-08-23 06:57:15

+0

特别是......我最近写了一个带有EF代码的基本文档管理系统,这个方法在我的C#代码中。我结束了3个类(FileSystemObject,目录,文件),后者2继承了第一个,并且我在数据库(目录,文件)中有2个表。 – War 2012-09-09 14:05:54