Recommand · June 13, 2021 0

Linq group result to list of object

I’m trying group a collection of data by it’s State but I’m stuck on the correct way to do this:

FileStateInfoDto

public class FileStateInfoDto : EntityDto<int>
{
    public string StateName { get; set; }
    public int StateNumber { get; set; }
    public int FilesByStateCount { get; set; }
}

FileGroupDto

public class FileGroupDto : EntityDto<int>
{
    public int CaseId { get; set; }

    public string Name { get; set; }

    public string ResourceKey { get; set; }

    public bool IsFolder { get; set; }

    public int SequenceNumber { get; set; }

    public IList<FileStateInfoDto> FileStateInfo { get; set; }

    public IList<FileGroupDto> FileGroups { get; set; }

    public IList<FileInfoDto> Files { get; set; }
}

Here is the code I have:

return await Context.FileGroups
    .Include(g => g.Case).Include(g => g.FileGroups).Include(g => g.Files)
    .Where(g => g.Id == fileGroupId && 
            g.CaseId == caseId &&
            g.Case.CaseState != CaseState.Approved &&
            g.Case.CaseState != CaseState.Submitted &&
            (g.Case.CaseState != CaseState.Draft || g.Case.CreatorUserId == userId))
    .OrderBy(g => g.SequenceNumber)
    .Select(g => new FileGroup
    {
        Id = g.Id,
        CaseId = g.CaseId,
        Name = g.Name,
        ResourceKey = g.ResourceKey,
        IsFolder = g.IsFolder,
        SequenceNumber = g.SequenceNumber,
        FileGroups = g.FileGroups,
        FileStateInfo = g.Files.GroupBy(f => f.State), <-- My problem
        Files = g.Files.Where(f => f.IsActive && f.State != FileApprovalState.Approved).Select(
                f => new File
                {
                    Id = f.Id,
                    CreationTime = f.CreationTime,
                    CreatorUserId = f.CreatorUserId,
                    Title = f.Title,
                    FileName = f.FileName,
                    URL = f.URL,
                    Size = f.Size,
                    KeepOnPortal = f.KeepOnPortal,
                    CreatorUserName = Context.Users.FirstOrDefault(u => u.Id == (f.CreatorUserId ?? 0)).UserName,
                    CreatorUserRole = Context.CasePersons.Where(p => p.CaseId == caseId && p.UserId == f.CreatorUserId).Take(1).Select(p => p.CaseRoleType.Title).FirstOrDefault()
                }
            ).ToList()
    }).FirstOrDefaultAsync();

I’m trying to figure out how I should write this line FileStateInfo = g.Files.GroupBy(f => f.State) so it will give the expected result as below.

FileStateInfo = [{"StateName":"Approved","StateNumber":1, "FilesByStateCount":22},
                 {"StateName":"NotApproved","StateNumber":2, "FilesByStateCount":11}]

The State in g.Files.GroupBy(f => f.State) is an enum that contains Approved and NotApproved

StateName = Name of the State.
StateNumber = The Integer assinged.
FilesByStateCount = The files count by this state.

I hope it’s possible because I’ve been trying to make this for a few days now.

I’ve tried things like this Post