简体   繁体   English

Linq分组和计数

[英]Linq group by and count

I'm trying to understand how groupy by and count works with linq but i can't get how to do what i want. 我试图了解linq的分组和计数方式,但是我不知道该怎么做。

I have this table: 我有这张桌子:

ASSET:
Id, Code, Name, ParentId

the ParentId is null if its the root, and contains the parent id if the asset is linked to another asset 如果ParentId是其根,则为null;如果该资产链接到另一个资产,则包含父ID。

I'd like to have for each root parents the Id and the number of children 我希望每个亲生父母都拥有身份证和孩子的数量

this is the query i used: 这是我使用的查询:

select father.Id, father.Code, COUNT(children.Id) As NumberOfChildren 
from Asset father 
left join Asset children on(father.Id = children.ParentId) 
where father.ParentId IS NULL 
group by father.Id, father.Code

this is the linq query i do 这是我做的linq查询

var query = from father in this.assetService.GetAll() 
                        join children in this.assetService.GetAll() 
                        on father.Id equals children.ParentId into Children 
                        from children in Children.DefaultIfEmpty() 
                        where father.ParentId.Value == null 
                        group father by new { id = father.Id, code = father.Code } into gf 
                        select new { id = gf.Key.id, count = gf.Count() };

but entity generates that query: 但实体会生成该查询:

SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [Id], 
    [GroupBy1].[A1] AS [C2] 
    FROM ( SELECT 
        [Extent1].[Id] AS [K1], 
        [Extent1].[Code] AS [K2], 
        COUNT(1) AS [A1] 
        FROM  [dbo].[Asset] AS [Extent1] 
        LEFT OUTER JOIN [dbo].[Asset] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ParentId] 
        WHERE [Extent1].[ParentId] IS NULL 
        GROUP BY [Extent1].[Id], [Extent1].[Code] 
    )  AS [GroupBy1]

the issue comes from the COUNT(1) , how can i tell thats its supposed to be COUNT(children.Id) 问题来自COUNT(1) ,我怎么能知道那应该是COUNT(children.Id)

You could try something like this: 您可以尝试这样的事情:

// Get all the assets in a list.
var assets = this.assetService.GetAll().ToList();

// Get the parents.
var parents = (from asset in assets
               where asset.ParentId == null);

// Remove parents from the original list.
var children = assets.RemoveAll(x => parents.Contains(x));

// Group the children by their parentId
var result = children.GroupBy(x => x.ParentId)
                     .Select(x => new { ParentId = x.Key, Count = x.Count() });

Since you want to deal with the NULL values in children.Id , you'll need a way to count them when you are selecting your final object. 由于要处理children.IdNULL值,因此需要一种在选择最终对象时对它们进行计数的方法。 To do this, you would group into a new object that you could query against in order to get the right count. 为此,您将分组为一个新对象,可以对其进行查询以获取正确的计数。 Here's the modified query object you're looking for: 这是您要查找的修改后的查询对象:

var query = from father in this.assetService.GetAll() 
                        join children in this.assetService.GetAll() 
                        on father.Id equals children.ParentId into Children 
                        from children in Children.DefaultIfEmpty() 
                        where father.ParentId.Value == null 
                        group new { father = father, childExists = (children != null) } by new { id = father.Id, code = father.Code } into gf 
                        select new { id = gf.Key.id, count = gf.Count(o => o.childExists) };

I used the following C# fiddle to test it, and it correctly returns 0 records if a parent has no children. 我使用以下C#小提琴对其进行测试,如果父级没有子级,它将正确返回0条记录。

https://dotnetfiddle.net/gyqpef https://dotnetfiddle.net/gyqpef

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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