Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有多种类型的实体框架(代码优先)设计思想_C#_Entity Framework_Ef Code First - Fatal编程技术网

C# 具有多种类型的实体框架(代码优先)设计思想

C# 具有多种类型的实体框架(代码优先)设计思想,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我不确定我处理实体设计的方式是否有缺陷,或者我是否基本上有缺陷,但需要更多的知识 我正在设计一个树状结构(递归),由节点描述,节点可以是树中的新级别、文件或帮助文章。文件和文章可以放置在树中的多个点上,因此文件和文章节点本质上是指向内容的指针 节点描述为: public class Node { public Enum NodeType { Node, File, Article }; public int Id

我不确定我处理实体设计的方式是否有缺陷,或者我是否基本上有缺陷,但需要更多的知识

我正在设计一个树状结构(递归),由节点描述,节点可以是树中的新级别、文件或帮助文章。文件和文章可以放置在树中的多个点上,因此文件和文章节点本质上是指向内容的指针

节点描述为:

public class Node
{
    public Enum NodeType
    {
        Node,
        File,
        Article
    };

    public int Id {get;set;}
    public string Description {get;set;}
    public int ParentId {get;set;}

    public NodeType Type {get;set;}
    public int TypeId {get;set;}

    public virtual Node Parent {get;set;}
    public virtual ICollection<Node> Children {get;set;}
}
这样做没有问题,你会得到你想要的。让我感到困扰的是,在
节点
类中,我有
虚拟
参数来访问父节点和子节点,而父节点和子节点又使用外键来完成工作,因此从任何
节点
向上或向下都非常容易(即不需要代码)

这样看来,我的设计应该允许我添加类似于
节点
类的内容,以便轻松访问内容对象,例如:

public virtual Article Article {get;set;}

但这似乎是错误的,因为您必须根据可能的类型添加一个新的虚拟机

另一种方法是让两种内容表类型都从某个基本类型继承,该基本类型只允许您添加一个虚拟表:

public class Base
{
    public int Id {get;set}
}

public class File : Base
{
    public byte[] Content {get;set;}
}

public class Article : Base
{        
    public string Content {get;set;}
}

// Node class then gets
public virtual Base Base {get;set;}
但是,现在您实际上没有访问内容的权限,除非您执行强制转换(您必须从类型中了解自己)


我是走错了路,还是快到了?

第一条路需要您支持逻辑指针。这意味着您不能简单地删除
文件
对象,您必须找到并删除相应的
节点
对象。大多数时候,这是个坏主意。但是如果你有这样一个“逻辑”关系的框架,或者你想创建一个框架,它会非常方便

根据我的经验,第二条路是正确的。如果是
文件
文章
,则需要检查
基本
对象的类型,但这是快速合法的操作

您也可以考虑制作<代码>文件名:NodeBase < /COD>和<代码> OutLooD: NodeBase类型>代码> >代码>文件> />代码> <代码>文章<代码>,但在很多情况下仍然需要类型检查。


需要了解的是,关系模型不像对象模型那样支持多态性。因此,对非具体类型的导航属性的每次调用都会导致对所有可以保存派生类型数据的表的多次连续请求。通常,这是瓶颈。

当我创建结构时,通过将
节点
类抽象,然后定义3个独立的子类,
节点
表最终有两个额外的列
Article\u Id
File\u Id
,它们在FK中用于相关内容表的
Id
(还有一个
Discriminator
列用于决定使用哪个子类)。问题是,当我添加内容节点时,
Article\u Id
File\u Id
列总是
null
TypeId
列(来自我的原始帖子)和内容之间没有明显的联系。code:,节点SQL:
public virtual File File {get;set;}
public class Base
{
    public int Id {get;set}
}

public class File : Base
{
    public byte[] Content {get;set;}
}

public class Article : Base
{        
    public string Content {get;set;}
}

// Node class then gets
public virtual Base Base {get;set;}