在实体框架6中投影自引用多级实体 [英] Projecting self referencing multi level Entities In Entity Framework 6

查看:17
本文介绍了在实体框架6中投影自引用多级实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Entity Framework 6 中投影自引用多级实体.

Projecting self referencing multi level entities in Entity Framework 6.

假设我有一个 Category 实体如下:

Let's say that I have a Category entity as follows:

public class Category
{
    public int CategoryId { get; set; }
    public int? ParentCategoryId { get; set; }        
    public string Name { get; set; }
    public string Description { get; set; }        

    public virtual Category ParentCategory { get; set; }

    public virtual ICollection<Category> SubCategories { get; set; }
    public virtual ICollection<Product> Products { get; set; }

    public Category()
    {            
        SubCategories = new HashSet<Category>();
        Products = new HashSet<Product>();
    }
}

我想将具有所有层次结构的整个 Category DbSet 映射到以下 POCO 类(同时包括子和父类别的所有可能级别):

And I would like to map the whole Category DbSet with all the hierarchy to a following POCO class (while including all possible levels of sub and parent categories):

public class CategoryView
{
    public int Id { get; set; }
    public int? ParentCategoryId { get; set; }        
    public string Name { get; set; }
    public string Description { get; set; }        

    public CategoryView ParentCategory { get; set; }

    public List<CategoryView> SubCategories { get; set; }

    public int ProductCount { get; set; }

    public Category()
    {            
        SubCategories = new HashSet<CategoryView>();            
    }
}

请记住,单个类别可能有无限级别的子类别,如下所示:

Please bear in mind that a single category may have unlimited levels of subcategories as follows:

Category (Level 0)
    SubCategory1 (Level 1)
    SubCategory2
        SubCategory2SubCategory1 (Level 2)
        SubCategory2SubCategory2
            SubCategory2SubCategory2SubCategory1 (Level 3)
            ... (Level N)
    SubCategory3

当尝试使用递归方法创建层次结构时,该方法尝试处理每个类别的子类别和父类别,得到 stackoverflow 异常,因为它卡在第一个类别(Category) 和第一个子类别 (SubCategory1) 由于 ParentCategorySubCategories 之间的关系.

When tried to create hierarchy with recursive a method which tries to process every single categories sub and parent categories, got stackoverflow exception, since it get stuck between the first category (Category) and the first subcategory (SubCategory1) due to relation between ParentCategory and SubCategories.

进行这种投影(不消除父母)的最佳和优雅的方式是什么?(或者有没有?)

What is the best and elegant way of doing such projection (without eliminating parents)? (Or is there any?)

任何帮助将不胜感激.

谢谢,

推荐答案

我不能说这是最好还是优雅的方式,但它是构建这种结构的非常标准且高效的非递归方式.

I can't say if it's the best or elegant way, but it's pretty standard and efficient non recursive way of building such structure.

首先使用简单的投影加载所有类别没有父/子对象链接:

Start with loading all categories without parent / child object links using a simple projection:

var allCategories = db.Categories
    .Select(c => new CategoryView
    {
        Id = c.CategoryId,
        ParentCategoryId = c.ParentCategoryId,
        Name = c.Name,
        Description = c.Description,
        ProductCount = c.Products.Count()
    })
    .ToList();

然后创建一个快速查找数据结构,用于通过Id查找CategoryView:

then create a fast lookup data structure for finding CategoryView by Id:

var categoryById = allCategories.ToDictionary(c => c.Id);

然后使用先前准备的数据结构将子类别链接到其父类别:

then link the subcategories to their parents using the previously prepared data structures:

foreach (var category in allCategories.Where(c => c.ParentCategoryId != null))
{
    category.ParentCategory = categoryById[category.ParentCategoryId.Value];
    category.ParentCategory.SubCategories.Add(category);
}

此时,树形链接已准备就绪.看你的需要.如果您需要真实的树表示,则返回 allCategories 或根类别:

At this point, the tree links are ready. Depending of your needs. either return the allCategories or the root categories if you need a real tree representation:

return allCategories.Where(c => c.ParentCategoryId == null);

附:实际上,可以避免 allCategories 列表,因为 categoryById.Values 可以起到相同的作用.

P.S. Actually the allCategories list can be avoided, since categoryById.Values could serve the same purpose.

这篇关于在实体框架6中投影自引用多级实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆