C# 计算自引用表中所有子体总数的最有效方法

C# 计算自引用表中所有子体总数的最有效方法,c#,entity-framework,automapper,C#,Entity Framework,Automapper,我正在寻找一种有效的方法来计算给定类别的所有子类别(所有级别)的总数,而无需从数据库检索所有数据 这是我的模型: public class Category { public Category() { SubCategories = new HashSet<Category>(); } public Guid CategoryId { get; set; } public string Title { get; set; }

我正在寻找一种有效的方法来计算给定类别的所有子类别(所有级别)的总数,而无需从数据库检索所有数据

这是我的模型:

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

    public Guid CategoryId { get; set; }
    public string Title { get; set; }

    [ForeignKey("ParentCategory")]
    public Guid? ParentCategoryId { get; set; }

    //navigation properties
    public virtual Category ParentCategory { get; set; }
    public virtual ICollection<Category> SubCategories { get; set; }
}
假设一个类别可以包含数千个子类别。由于这将是SOA解决方案,并且数据将从Web API传递到我的客户端应用程序中,所以我不想在每次Web API调用中传递所有子类别数据,所以我只需要请求的类别和相应计数的数据

假设我们有 “第1类”>“第11类”>“第1类”

“第1类”仅包含2个子类别“1类”包含一个子类别。我可以通过调用web API方法“getCategory(null)”来检索“cat 1”数据,要检索“cat 1 1”数据,我将调用“getCategory(GuidOffcat11)”

对于“第一类”:

直接子类别总计-1

所有子类别总计-2


同样,不会包含任何子类别

以下是我可以实现的最佳方法,您认为有更好的方法吗:

自动映射器:

            cfg.CreateMap<Category, CategoryViewModel>()
            .PreserveReferences()
            .ForMember(x => x.TotalOfDirectSubCategories, x => x.MapFrom(z => z.SubCategories.Count))
            .ReverseMap();
            cfg.CreateMap<Category, CategoryViewModel>()
            .PreserveReferences()                
            .ReverseMap();
                data = _ctx.Categories.Where(x => x.ParentCategoryId == categoryId)
                //.Include(x => x.SubCategories)
                .ToList();
            cfg.CreateMap<Category, CategoryViewModel>()
            .PreserveReferences()
            .ForMember(x => x.TotalOfDirectSubCategories, x => x.MapFrom(z => z.SubCategories.Count))
            .ReverseMap();
        public List<CategoryViewModel> GetAllCategoriesAndTasksForParentCategoryAndUser(Guid? categoryId)
    {
        var data = new List<Category>();

        if (categoryId == null) // retrieve root level categories
        {
                data = _ctx.Categories.Where(x => x.ParentCategoryId == null)
                    .Include(x => x.SubCategories)
                    .Include(x => x.Tasks)
                    .ToList();
        }
        else
        {
                data = _ctx.Categories.Where(x => x.CategoryId == categoryId)
                    .Include(x => x.SubCategories)
                    .Include(x => x.Tasks)
                    .ToList();
        }

        var dataToReturn = Mapper.Map<List<Category>, List<CategoryViewModel>>(data);
        foreach (var category in data)
        {
            var vm = dataToReturn.First(x => x.CategoryId == category.CategoryId);

            //subCategories
            int totalCount = 0;
            SubCategoriesCount(ref totalCount, category);
            vm.TotalOfAllSubCategories = totalCount;            
        }

        return dataToReturn;

    }
    private void SubCategoriesCount(ref int subCatCount, Category category)
    {
        if (category.SubCategories != null || category.SubCategories.Count() != 0)
        {
            subCatCount += category.SubCategories.Count();

            foreach (var subCat in category.SubCategories)
            {
                SubCategoriesCount(ref subCatCount, subCat);
            }
        }
    }