使用 LINQ to GroupBy 两列并用它们构建字典?

Use LINQ to GroupBy two columns and build a dictionary with them?

我正在尝试使用 LINQ 来构建一个记录,该记录按其存储首选项排序并具有与每个 CompletionStatusFlag 关联的应用程序列表。为了做到这一点,我的第一个想法是让记录保存一个 StorePreference,然后有一个根据 CompletionStatus 分隔应用程序的字典。

员工申请

public class EmployeeApplication
{
     public int Id { get; set; }
     public StorePreference { get; set; }
     public CompletionStatusFlag CompletionStatus { get; set; }
}

ApplicationCountRecord

public class ApplicationCountRecord
{
    public Store StorePreference { get; set; }
    public Dictionary<CompletionStatusFlag, List<EmployeeApplication>> StatusApplicationPairs { get; set; } 
            = new Dictionary<CompletionStatusFlag, List<EmployeeApplication>>();
    public int TotalCount => StatusApplicationPairs.Count();
}

尝试创建字典时出现问题。我已保存完成状态,但如何获取与完成状态匹配的当前应用程序以便将它们传递到字典中?

public void ConvertAppsToResults()
{
   var applications = _appRepo.Query()
       .GroupBy(x => new { x.StorePreference, x.CompletionStatus })
       .Select(y => new ApplicationCountRecord()
       {
            StorePreference = y.Key.StorePreference,
            //Somehow create dictionary here.
       });
}

这是另一个甚至无法编译的错误尝试,但它可能会帮助您了解我的思考过程。

public void ConvertAppsToResults()
{
    //get apps in DateFilter range, and creates records seperated by StorePreference, and CompletionStatus
    var applications = _applicationRepo.Query()
                .GroupBy(x => new { x.StorePreference1, x.CompletionStatus })
                .Select(y => new ApplicationCountRecord()
                {
                    StorePreference = y.Key.StorePreference,
                    StatusApplicationPairs = new Dictionary<CompletionStatusFlag, List<EmployeeApplication>>()
                    .Add(y.Key.CompletionStatus, y.Where(x => x.CompletionStatus == y.Key.CompletionStatus).ToList());
                });
}

这里有一个双重分组,这可能是您混淆的根源

employeeApplications
  .GroupBy(ea => ea.Store)
  .Select(g => new ApplicationCountRecord()
    {
      StorePreference = g.Key
      StatusApplicationPairs = g.GroupBy(ea => ea.CompletionStatus).ToDictionary(g2 => g2.Key, g2 => g2.ToList())
    }
  )

假设您有 100 个 EmployeeApplications,跨越 10 个商店,并且有 5 个状态,每个状态有 2 个应用程序。 2 个应用 * 5 个状态 * 10 个商店 = 100 个应用程序

GroupBy(Store) 获取您的列表,例如100 个 EmployeeApplications(每个商店 10 个)并将其分组为 10 个 IGrouping,每个 IGrouping 在概念上都是 10 个 EmployeeApplications 的列表。 Store1 的 10 IGrouping、Store2 的 10 IGrouping 等..

Select 遍历 10 个分组,并在每个 g 上运行(请记住,它的行为类似于所有具有相同 Store 的 EmployeeApplications 列表,在 g.Key 中给出) 它通过在 CompletionStatus 上调用 GroupBy(CompletionStatus) 进一步细分 g 中的 10 个 EA 来再次分组。 10 个 EA,例如“Store 1”被分成 5 个 IGroupings(5 种状态),每个内部分组中有 2 个 EA,然后对 Store 2、3 等执行相同的过程。因此有 5 g2.Keys,每个一个5 种状态中的每一种 g2

有 2 个 EA

ToDictionary 在分组后被调用,所以你得到一个包含 5 个键的字典,每个键与 2 个应用程序的列表相关。 ToDictionary 有两个参数;什么用于键(g2.Key 是一个 Status)以及什么用于值(g2.ToList() 实现了一个 List<EmployeeApplication>


= new Dictionary<CompletionStatusFlag, List<EmployeeApplication>>(); 在 AppCountRecord 中是不必要的,因为它无论如何都会被替换