使用LINQ从模型中获取父名称和子计数

时间:2017-08-08 15:27:54

标签: c# entity-framework linq asp.net-core entity-framework-core

我有以下型号:

public Class Category{
   public int Id {get;set;}
   public string Name {get;set;}
   public ICollection<SubCategory> SubCategories {get;set;}
}

public Class SubCategory{
   public int Id {get;set;}
   public string Name {get;set;}
   public int CategoryId { get; set; }
   public virtual Category Category{ get; set; }
   public ICollection<Ticket> Tickets { get; set; }
}

public class Ticket {
    public Ticket();

    public int Id { get; set; }
    public virtual SubCategory SubCategory{ get; set; }
    public int SubCategoryId{ get; set; }   
}

我想获取数据groupBy类别并使用此查询获取每个子类别中的票证数量:

Entities
                .Include(h => h.SubCategories )
                .ThenInclude(s => s.Tickets)
                .GroupBy(s => s.Id)
                .Select(t => new Cata {
                    Name = t.FirstOrDefault().Name,
                    Children = GetChildern(t.FirstOrDefault().SubCategories )
                });



public List<SubCat> GetChildern(IEnumerable<SubCategories> subs)
        {
            var output = new List<SubCat>();
            foreach (var sub in subs) {
                var subcat = new SubCat();
                subcat.Name = sub.Name;
                if (sub.Tickets != null) {
                    subcat.Size = sub.Tickets.Count;
                }
                output.Add(subcat);
            }
            return output;
        }

使用上面的查询,故障单总是为零,但故障单存在。

2 个答案:

答案 0 :(得分:3)

如果您在分类

中启动查询,我不明白为什么您需要执行分组操作
var result=  Entities
            .Include(h => h.TicketSubCategories)
            .ThenInclude(s => s.Tickets)
            .Select(t => new Cata {
                            Name = t.Name,
                            Children= t.TicketSubCategories
                                       .Select(ts=>new SubCat{
                                                     Name=ts.Name,
                                                     Count=ts.Tickets.Count()})
                         };

同意@Ivan关于他上面评论的内容,在这里您不需要使用自定义方法,使用它会强制您的查询投影在客户端执行而不是在服务器(您的数据库)上执行

答案 1 :(得分:1)

因此每个类别都有零个或多个SubCategories,每个SubCategory都有零个或多个Tickets。每个Ticket只属于一个SubCategory,每个SubCategory只属于一个Category

并且您想要一个查询,这会产生具有相同类别的SubCategories组。您需要每个SubCategory的一些(或所有)属性,但最重要的是,您需要每个SubCategory具有的Tickets数量。

每组SubCategories中的所有元素属于同一类别。您还需要此类别的一些(如果不是全部)属性。

解决方案是将所有SubCategories分组到相同类别的组中(为了提高效率使用CategoryId)。然后使用Select来获取所需的属性。

var result = SubCategories 
    // group them into groups with same CategoryId
    .GroupBy(subCategory => subCategory.CategoryId
    // from every group take the properties you want: 
    .Select(group => new
    {
        // All SubCategories in one group belong to the same Category.
        // For efficiency, take only the Category properties you plan to use,
        CommonCategory = group.Key.Select(category => new
        {
            // take the category properties you want to use
        }

        // The group has a lot of SubCategories.
        // For each subcategory select only the properties you want to use
        SubCategories = group.Select(subCategory => new
        {
            // one of the properties you want is the number of Tickets of this SubCategory:
            TicketCount = subCategory.Tickets.Count(),

            // for efficiency: select only SubCategory properties you plan to use:
            Property1 = subCategory.Property1,
            Property2 = subCategory.Property2,
            ...
        }),
    });

结果是一系列对象。每个对象都有两个属性:

  • 子类别:属于同一类别的所有子类别的一些属性的序列。
  • CommonCategory。所有子类别所属的类别的几个属性。

SubCategories是一个序列。序列的每个元素都是具有多个属性的对象:

  • TicketCount:SubCategory中的票数
  • 其他属性:SubCategory的其他几个属性

由此可以很容易地将代码构造为GetChildren