简体   繁体   中英

Self Referencing list item count from parent to to last child

i have a self referencing list of categories , where each category have list of children and in the same time have a list of items . example category1 (has 3 items, has 1 children subcategory ) subcategory (has 1 item,has parent category1, has no children ) when i fetch the list of categories i included the item count , so i am expecting to get with category1 ( itemcount = 4 ) but what i am getting is 3

public class Category {
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }
    public virtual Category Parent { get; set; }
    public virtual ICollection<Category> Children { get; set; }
    public ICollection<Item> Items { get; set; }
}

and below is the dto

public class CategoryForReturnDto
{
     public string Name { get; set; }
     public int Id { get; set; }
     public int ItemsCount { get; set; }
     public ICollection<Category> Children { get; set; }
     public int ParentId { get; set; }
}

and finaly the automapper

        CreateMap<Category, CategoryForReturnDto> ()
            .ForMember (dest => dest.ItemsCount, opt => {
                opt.MapFrom (src => src.Items.Count);
            });

the item model is

public class Item {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<ItemPhoto> Photos { get; set; }
    public Category Category { get; set; }
    public int CategoryId { get; set; }
}

DB example:

在此处输入图片说明

在此处输入图片说明

You say yourself

example category1 (has 3 items, has 1 children subcategory )

so ItemCount correctly returns 3. That's exactly what you're telling it to return:

opt.MapFrom (src => src.Items.Count);

I don't see any collection or property in the DTO for SubCategories; until you get them included, you can't get the number you want. (I'm not sure what you would call the number you want; ItemCount is misleading.)

the solution was to add a function

    static int RecursiveItemsCount (Category cat, int count) {
        count += cat.Items.Count ();
        foreach (var child in cat.Children) {
            count += RecursiveItemsCount (child, 0);
        }
        return count;
    }

and inside the automapper

        CreateMap<Category, CategoryForReturnDto> ()
            .ForMember (dest => dest.ItemsCount, opt => {
                int number = 0;
                opt.ResolveUsing (src => {
                    return RecursiveItemsCount (src, number);
                });
            });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM