使用 LINQ SelectMany() 在没有导航的情况下连接多个子表 属性

Using LINQ SelectMany() to join multiple child tables without a navigation property

我对如何实现我想要的东西有点困惑,在互联网上搜索后,我认为 SelectMany() 是可行的方法,但我对如何实现它感到迷茫( 我认为我对 lambda 表达式的工作原理的理解非常薄弱)..

我的目标是能够使用 LINQ 来填充这个 class:

public class AttendanceList
{
    public int AttendancePeriodId { get; set; }     // from AttendancePeriod class
    public int Activity { get; set; }               // from DailyAttendance class
    public string Name { get; set; }                // from Employee class
    public string Position { get; set; }            // from Employee class
    public string Department { get; set; }          // from Employee class
}

我有一个完全错误的非工作代码,但为了说明,我想使用类似的东西:

var query = context.AttendancePeriod
    .Include(i => i.DailyAttendance)
    .Include(i => i.DailyAttendance).ThenInclude(ii => ii.Employee)
    .Select(s => new AttendanceList
    {
        AttendancePeriodId = s.Id,
        Activity = ...,
        Name = ...,
        Position = ...,
        Department = ...
    });

如何使用 SelectMany() 实现上述目标?

作为参考,这些是我的 classes:

public class AttendancePeriod
{
    public int Id { get; set; }
    public DateTime From { get; set; }
    public DateTime To { get; set; }
    public ICollection<DailyAttendance> DailyAttendances { get; set; }
}

public class DailyAttendance
{
    public int Id { get; set; }
    public Employee Employee { get; set; }
    public TimeSpan TimeIn { get; set; }
    public TimeSpan TimeOut { get; set; }
    public string Activity { get; set;}
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }
    public string Department { get; set; }
}

未经测试且没有任何空检查:

var query = context.AttendancePeriod
  // .Include(i => i.DailyAttendance)  
  // .Include(i => i.DailyAttendance).ThenInclude(ii => ii.Employee)
   .SelectMany(s => s.DailyAttendances.Select(a => 
      new AttendanceList
      {
          AttendancePeriodId = s.Id,
          Activity = a.Activity ,
          Name = a.Employee.Name,
          Position = a.Employee.Position,
          Department = a.Employee.Department,
      }));

也许您正在寻找这个

第一步获取所有DailyAttendances

的平面列表
.SelectMany(x => x.DailyAttendances)

现在transform那些变成AttendanceList

.Select(x => new AttendanceList
{
    //x is of type `DailyAttendance`

    AttendancePeriodId = x.AttendancePeriod.Id,
    Activity = x.Activity,
    Name = x.Employee.Name,
    Position = x.Employee.Position,
    Department = x.Employee.Department,
}

如果 DailyAttendance 没有 AttendancePeriod 的成员,您可以执行以下操作,而不是

.SelectMany(x => x.DailyAttendances)

使用这个,这将创建一个包含 x = AttendancePeriod 和 y = DailyAttendance 的元组

.SelectMany(x => x.DailyAttendances.Select(y => (x, y))

现在transform变成这个

.Select(x => new AttendanceList
{
    //x is of type `ValueTuple<AttendancePeriod, DailyAttendance>`
    //x.Item1 is of type AttendancePeriod
    //x.Item2 is of type DailyAttendance

    AttendancePeriodId = x.Item1.Id,
    Activity = x.Item2.Activity,
    Name = x.Item2.Employee.Name,
    Position = x.Item2.Employee.Position,
    Department = x.Item2.Employee.Department,
}