首页 > 解决方案 > EF Core - 使用复合设计模式和 CTE 的层次结构

问题描述

我想创建一个目录产品。每个节点上可能有目录或产品。

我决定使用复合设计模式。

我将使用 CTE 与孩子一起下载节点。不幸的是,出现了一个问题,因为 EF Core 没有在 CategoryProducts 表中添加 parentId。此外,类(Category as my Composite)有自己的 CategoryDe​​tails 类,(Product as my Leaf)有自己的 ProductDetails 类。

如何配置 EF Core 以递归方式从树中获取节点?CTE 是个好主意吗?

public enum CategoryProductType
{
    Category,
    Product
}

public abstract class CategoryProduct
{
    public Guid Id { get; private set; }
    public string Name { get; private set; }
    public CategoryProductType Type { get; private set; }

    protected CategoryProduct(Guid id, string name, CategoryProductType type)
    {
        Id = id;
        Name = name;
        Type = type;
    }

}

public class Category : CategoryProduct
{
    public string Code { get; private set; }
    public CategoryDetails CategoryDetails { get; private set; }

    private ICollection<CategoryProduct> _children { get; set; } = new Collection<CategoryProduct>();
    public IEnumerable<CategoryProduct> Children => _children;

    public Category(Guid id, string name, string code) 
        : base(id, name, CategoryProductType.Category) 
    {
        Code = code;
    }

}

public class CategoryDetails
{
    public Guid CategoryId { get; private set; }
    public Category Category { get; private set; }
    public string Description { get; private set; }

    private CategoryDetails() { }

    public CategoryDetails(Category category, string description)
    {
        Category = category);
        Description = description);
    }

}

public class Product : CategoryProduct
{
    public string Index { get; private set; }
    public ProductDetails ProductDetails { get; private set; }

    public Product(Guid id, string name, string index) 
        : base(id, name, CategoryProductType.Product) 
    {
        SetIndex(index);
    }

}

EF 核心设置:在此处输入图像描述

标签: entity-framework-corecomposite

解决方案


不幸的是,我对 CTE 递归一无所知。

但是,这是一个关于我如何使用 EF Core 对层次结构(即树)建模的示例,希望它可以帮助您。

public class TreeNode
{
    public int TreeNodeId { get; private set; }
    public int? ParentTreeNodeId { get; set; }
    public TreeNode ParentTreeNode { get; set; }
    public List<TreeNode> ChildrenTreeNodes { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<TreeNode>(entity =>
    {
        entity.HasOne(n => n.ParentTreeNode)
            .WithMany(n => n.ChildrenTreeNodes)
            .HasForeignKey(n => n.ParentTreeNodeId);
    });
}

推荐阅读