LINQ:从投影中的嵌套列表中获取总计数

LINQ: Get a total count from a nested list inside projection

我有以下 LINQ 语句:

var branchStatus = (from b in context.Branches
    join l in context.Lobbies on b.BranchId equals l.BranchId into branchLobbyDetails
    from bl in branchLobbyDetails.DefaultIfEmpty()
    where (branches.Count == 0 || branches.Contains(bl.BranchId)) 
        && b.IsActive 
        && (bl == null ? true : bl.IsActive && !bl.IsArchived)
    group bl by new { b.BranchId, b.BranchName } into grouped
    select new BranchStatusDetailsDto
    {
        Id = grouped.Key.BranchId.ToString(),
        BranchName = grouped.Key.BranchName,
        WaitingInLobby = (grouped.Any() && grouped.First() != null) ? grouped.Count(l => l.Status == 1).ToString() : defaultEmpty,
        TotalPSProvided = (grouped.Any() && grouped.First() != null) ? grouped.Where(l => l.Status != 6).Select(l => l.ServicesProvided).Count().ToString() : defaultEmpty,
        AverageAssistTime = (grouped.Any() && grouped.First() != null) ? grouped.Where(l => l.Status == 5).Select(l => (TimeSpan)(l.CompletedTime - l.AssistedTime)).Average().ToString() : string.Empty    
    });

我基本上是在收集列表中每个分支的统计数据。在投影语句中,第一个计算 (WaitingInLobby) 没问题,我遇到了 TotalPSProvidedAverageAssistTime 的问题。

对于每个分支,可以有多个大厅记录,每个大厅记录可以有 0 个或多个 ServicesProvided 条目。使用 TotalPSProvided 我想获得每个分支的总数,但我得到的是不正确的 - 似乎当前查询给出的大厅记录数为 TotalPSProvided

如何将语句修改为 return 正确的统计数据?

添加实体定义:

public partial class Branch
{
    public int BranchId { get; set; }
    public string BranchName { get; set; }
    public string BranchCode { get; set; }
    public string TimeZoneId { get; set; }
    public bool IsActive { get; set; }
    public DateTime LastModifiedDate { get; set; }
}

    public partial class Lobby
{
    public Lobby()
    {
        this.ServicesRequested = new List<ServicesRequested>();
        this.ServicesProvided = new List<ServicesProvided>();
    }

    [Key]
    [Required]
    public long LobbyId { get; set; }

    [Required]
    [ForeignKey("Branch")]
    public int BranchId { get; set; }

    [ForeignKey("UserRequested")]
    public int? RequestedUserId { get; set; }

    [ForeignKey("GroupRequested")]
    public int? RequestedGroupId { get; set; }

    [ForeignKey("AddedByUser")]
    public int? AddedByUserId { get; set; }

    [ForeignKey("AssistedByUser")]
    public int? AssistedByUserId { get; set; }

    [MaxLength(1000)]
    public string Comments { get; set; }

    [Required]
    public DateTime? AddedTime { get; set; }


    public DateTime? AssistedTime { get; set; }


    public DateTime? CompletedTime { get; set; }

    [Required]
    public bool IsActive { get; set; }


    public bool IsArchived { get; set; }

    //[ForeignKey("LobbyStatus")]
    public int Status { get; set; }

    [MaxLength(50)]
    public string AccountNumber { get; set; }

    [MaxLength(50)]
    [Required]
    public string FirstName { get; set; }

    [MaxLength(50)]
    [Required]
    public string LastName { get; set; }

    //[ForeignKey("Appointment")]
    public long? FkAppointmentId { get; set; }

    [MaxLength(150)]
    public string Notes { get; set; }

    [MaxLength(20)]
    public string PhoneNumber { get; set; }

    [MaxLength(50)]
    public string EmailAddress { get; set; }

    [MaxLength(2)]
    //[Required]
    [ForeignKey("PreferredLanguage")]
    public string PreferredLanguageKey { get; set; }

    [Required]
    public bool ClosedByAutoWrapUp { get; set; }

    /// <summary>
    /// Stores the requested services as a pre-calculated string to support sorting
    /// </summary>
    public string RequestedServices { get; set; }


    public DateTime? AddedLocalTime { get; set; }


    public DateTime? AssistedLocalTime { get; set; }


    public DateTime? CompletedLocalTime { get; set; }

    [MaxLength(4)]
    public string AccountNoLastFourDigits { get; set; }

    [Required]
    public DateTime LastModifiedDate { get; set; }

    public virtual Branch Branch { get; set; }
    public virtual User UserRequested { get; set; }
    public virtual Group GroupRequested { get; set; }
    public virtual User AssistedByUser { get; set; }
    public virtual Language PreferredLanguage { get; set; }
    public virtual List<ServicesProvided> ServicesProvided { get; set; }
    public virtual List<ServicesRequested> ServicesRequested { get; set; }
}

public partial class ServicesProvided
{
    [Key]
    [Required]
    public long ServiceProvidedId { get; set; }

    [Required]
    [ForeignKey("Lobby")]
    public long LobbyId { get; set; }

    [Required]
    [ForeignKey("Service")]
    public int ServiceId { get; set; }

    [Required]
    public DateTime LastModifiedDate { get; set; }

    public virtual Lobby Lobby { get; set; }

    public virtual Service Service { get; set; }
}

我认为这是您查询中的错字,您在计算 ServicesProvided 而不是将它们相加,您这样做:

TotalPSProvided = (grouped.Any() && grouped.First() != null) ? grouped.Where(l => l.Status != 6).Select(l => l.ServicesProvided).Count().ToString() : defaultEmpty,

而不是这个:

TotalPSProvided = (grouped.Any() && grouped.First() != null) ? grouped.Where(l => l.Status != 6).Sum(l => l.ServicesProvided).ToString() : defaultEmpty,

TotalPSProvided 的问题在行中:

grouped.Where(l => l.Status != 6).Select(l => l.ServicesProvided).Count()

这里只是统计满足where条件的(branch,lobby)对的数量。

返工为:

TotalPSProvided = (grouped.Any() && grouped.First() != null) 
                    ? grouped.Where(l => l.Status != 6)
                             .Sum(l => l.ServicesProvided.Count()).ToString() 
                    : defaultEmpty,