2017-07-06 1 views
0

Ich suche nach einer effizienten Möglichkeit, die Gesamtzahl aller Unterkategorien (alle Ebenen) für eine bestimmte Kategorie zu berechnen, ohne alle Daten aus der Datenbank abzurufenDie effizienteste Methode zur Berechnung der Gesamtzahl aller Nachkommen in der Selbstreferenztabelle

Hier ist mein Modell:

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; } 
} 

Und mein Viewmodel:

public class CategoryViewModel 
{ 
    public CategoryViewModel() 
    { 
     SubCategories = new List<CategoryViewModel>(); 
    } 

    public Guid CategoryId { get; set; } 

    [Required] 
    public string Title { get; set; } 

    public Guid? ParentCategoryId { get; set; } 

    public virtual CategoryViewModel ParentCategory { get; set; } 

    public virtual List<CategoryViewModel> SubCategories { get; set; } 

    public int TotalOfDirectSubCategories { get; set; } 
    public int TotalOfAllSubCategories { get; set; } 
} 

Mein Automapping:

  cfg.CreateMap<Category, CategoryViewModel>() 
      .PreserveReferences()     
      .ReverseMap(); 

Und schließlich meine EF Daten abzurufen:

   data = _ctx.Categories.Where(x => x.ParentCategoryId == categoryId) 
       //.Include(x => x.SubCategories) 
       .ToList(); 

ist eine Kategorie Tausende von Unterkategorien enthalten Lassen annehmen kann. Da dies eine SOA-Lösung sein wird und Daten von der Web-API in meine Client-App übertragen werden, möchte ich nicht alle Unterkategorien mit jedem Web-API-Aufruf übergeben, so dass ich nur Daten für die angeforderte Kategorie und die entsprechenden Zählungen benötige.

Nehmen wir an, wir haben 'cat 1'> 'cat 1 1'> 'cat 1 1 1'

'cat 1' enthält genau 2 Unterkategorien. 'Katze 1 1' enthält eine Unterkategorie. Ich kann durch den Aufruf von Web-API-Methode 'getCategory (null)', 'cat 1' Daten abrufen und 'cat 1, 1' zum Abrufen von Daten Ich würde nennen 'getCategory (GuidOfCat11)'

für 'cat 1':

TotalOfDirectSubCategories - 1

TotalOfAllSubCategories - 2

Und wieder werden keine Subkategorien

Antwort

0

Hier enthalten ist das beste, was ich umsetzen könnte, glauben Sie sich ein besserer Ansatz ist:

AutoMapper:

  cfg.CreateMap<Category, CategoryViewModel>() 
      .PreserveReferences() 
      .ForMember(x => x.TotalOfDirectSubCategories, x => x.MapFrom(z => z.SubCategories.Count)) 
      .ReverseMap(); 

Bestücken CategoryViewModel:

 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; 

    } 

Und schließlich die Methode:

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); 
      } 
     } 
    } 
Verwandte Themen