实体框架复杂的树状结构

本文关键字:结构 框架 复杂 实体 | 更新日期: 2023-09-27 18:21:54

我有一个复杂的树结构,我正试图使用代码优先的方法创建它。主要的想法是一个有一群孩子的班级。每个子级可以由相同类型的类本身(Folder)或某个其他类(File)。这可以在编程语言中通过从相同的基本接口派生的两个类来实现。这就是我更愿意代表我的类的方式:

public interface IBasicTreeItem
{
    string DisplayName { get; }
}
public class Folder : IBasicTreeItem
{
    public int Id { get; set; }
    public string DisplayName { get; set; }
    // This collection should be able to hold both Folder and File types
    public virtual ICollection<IBasicTreeItem> Children { get; set; }
    // Following 2 properties represent the parent folder
    // The file may not have a parent - in this case, it will be positioned in the root
    public int? FolderId { get; set; }
    public Folder ParentFolder { get; set; }
}
public class File : IBasicTreeItem
{
    public int Id { get; set; }
    public string DisplayName { get; set; }
    // Following 2 properties represent the parent folder
    // The file may not have a parent - in this case, it will be positioned in the root
    public int? FolderId { get; set; }
    public Folder ParentFolder { get; set; }
}

问题是,这不适用于数据库,至少不是以这种简单的方式,这就是我需要一些帮助来找出如何正确构建类的地方。

我尝试过的另一件事是首先创建数据库并从中生成C#对象(File表对Folder表有外键,Folder表对自己也有外键)-这导致了一些错误,但我可以看到它建议的基本思想-Folder类中的两个集合,它可以容纳的每个子类型一个(这不是我所希望的解决方案,因为我必须实现某种中间集合,它必须将两个集合联合起来)。

实体框架复杂的树状结构

您可以将Folder的文件和文件夹分离为两个不同的集合-两个表,并实现Folder类的一些未映射属性,以返回您的文件和文件到IBasicTreeItem

public interface IBasicTreeItem
{
    int Id { get; set; }
    string DisplayName { get; set; }
    int? FolderId { get; set; }        
}
public class BasicTreeItem : IBasicTreeItem 
{
    public int Id { get; set; }
    public string DisplayName { get; set; }
    public int? FolderId { get; set; }        
}
public class Folder : BasicTreeItem
{   
    public Folder ParentFolder { get; set; } 
    public virtual ICollection<Folder> Folders { get; set; }
    public virtual ICollection<File> Files { get; set; }
    [NotMapped]
    public ICollection<IBasicTreeItem> Content { get {
       return Files.Concat(Folders).Cast<IBasicTreeItem>();
    } }
}
public class File : BasicTreeItem
{
    public Folder ParentFolder { get; set; }
}