我如何计算 LINQ 中按日期分组的布尔值列?
How do i count a column of bools grouped by date in LINQ?
我有一个 table,按日期可容纳 15 session 个预订。每行都是他们参加的 session 的人员数据库条目。
对于每个日期,我需要计算每个 session S1、S2 等
的布尔值
2019 年 1 月 1 日的 S1 有多少人?
这里是 asp.net 核心中的 table
![table][https://imgur.com/a/SguJmLI]
的图片
看起来像这样
Session S1 S2 S3 S4 S5 S6 S7
1/1/2019 1 0 1 1 1 0 1
1/1/2019 0 1 1 1 1 1 1
2/1/2019 0 0 1 1 1 1 1
2/1/2019 0 1 1 1 1 1 1
有多个 session 日期,我需要获取每个日期的布尔值汇总计数。
1/1/2019 1 1 2 2 2 1 2
2/1/2019 0 1 2 2 2 2 2
遗憾的是我没有任何东西可以生成
但这就是我生成网格的方式
return View(await _context.SeatBooking
.OrderByDescending(s => s.SeatDate)
.ToListAsync());
我想你可以试试这个:
_context.SeatBooking.Select(i => i.Session).Distinct().Select(i =>
new
{
Session = i,
S1 = _context.SeatBooking.Count(j => j.Session == i && j.S1 == 1),
S2 = _context.SeatBooking.Count(j => j.Session == i && j.S2 == 1),
}
).OrderByDescending(s => s.Session).ToList();
由于列的类型是 bool
,首先要做的是将 bool
转换为 int
。
Func<bool, int> convertBoolToInt = flag => flag ? 1 : 0;
var query = _context.SeatBooking
.Select(s => new SeatBookingDto
{
SeatDate = s.SeatDate,
S1 = convertBoolToInt(s.S1),
S2 = convertBoolToInt(s.S2),
S3 = convertBoolToInt(s.S3),
S4 = convertBoolToInt(s.S4),
S5 = convertBoolToInt(s.S5),
S6 = convertBoolToInt(s.S6),
S7 = convertBoolToInt(s.S7),
});
现在我们可以分组并计算每组每列的总和:
query.GroupBy(m => m.SeatDate, m => m, (k, g) => new
{
Date = k,
S1= g.Sum(m=>m.S1),
S2= g.Sum(m=>m.S2),
S3= g.Sum(m=>m.S3),
S4= g.Sum(m=>m.S4),
S5= g.Sum(m=>m.S5),
S6= g.Sum(m=>m.S6),
S7= g.Sum(m=>m.S7),
})
如果您使用的是 EFCore,则相应的查询和结果为:
App> SELECT [s].[SeatDate], [s].[S1], [s].[S2], [s].[S3], [s].[S4], [s].[S5], [s].[S6], [s].[S7]
App> FROM [SeatBooking] AS [s]
App> ORDER BY [s].[SeatDate]
App> 1/1/2019 12:00:00 AM : 1,1,2,2,2,1,2
App> 2/1/2019 12:00:00 AM : 0,1,2,2,2,2,2
注意这里的 LINQ 表达式 g.sum()
都是在本地求值的,这意味着不由数据库求值。 EFcore 似乎还没有进化到能够将 Aggregate
表达式(例如 Sum
)转换为可以在服务器上执行的 SQL 查询。
如果你只想查询内存中的对象,还有另一种方法可以做到这一点(EFCore 尚不支持):
query.GroupBy(m=>m.SeatDate,m=>m,(k,g)=>new {
Date = k,
Count = g.Aggregate((c,n)=>new SeatBookingDto{
SeatDate=c.SeatDate,
S1=c.S1+n.S1,
S2=c.S2+n.S2,
S3=c.S3+n.S3,
S4=c.S4+n.S4,
S5=c.S5+n.S5,
S6=c.S6+n.S6,
S7=c.S7+n.S7,
})
})
谢谢大家,
只是一个快速更新,这似乎对我有用,但它很笨重
ViewData["CountSessions"] = _context.SeatBooking
// .Where(s => s.StudentEmail == _userManager.GetUserId(User))
.GroupBy(d => d.SeatDate)
.Select(s => new
{
SumS1 = s.Count(c => c.S1 == true),
SumS2 = s.Count(c => c.S2 == true),
SumS3 = s.Count(c => c.S3 == true),
SumS4 = s.Count(c => c.S4 == true),
SumS5 = s.Count(c => c.S5 == true),
SumS6 = s.Count(c => c.S6 == true),
SumS7 = s.Count(c => c.S7 == true),
SumS8 = s.Count(c => c.S8 == true),
SumS9 = s.Count(c => c.S9 == true),
SumS10 = s.Count(c => c.S10 == true)
}).ToListAsync();
我有一个 table,按日期可容纳 15 session 个预订。每行都是他们参加的 session 的人员数据库条目。
对于每个日期,我需要计算每个 session S1、S2 等
的布尔值2019 年 1 月 1 日的 S1 有多少人?
这里是 asp.net 核心中的 table
![table][https://imgur.com/a/SguJmLI]
的图片看起来像这样
Session S1 S2 S3 S4 S5 S6 S7
1/1/2019 1 0 1 1 1 0 1
1/1/2019 0 1 1 1 1 1 1
2/1/2019 0 0 1 1 1 1 1
2/1/2019 0 1 1 1 1 1 1
有多个 session 日期,我需要获取每个日期的布尔值汇总计数。
1/1/2019 1 1 2 2 2 1 2
2/1/2019 0 1 2 2 2 2 2
遗憾的是我没有任何东西可以生成
但这就是我生成网格的方式
return View(await _context.SeatBooking
.OrderByDescending(s => s.SeatDate)
.ToListAsync());
我想你可以试试这个:
_context.SeatBooking.Select(i => i.Session).Distinct().Select(i =>
new
{
Session = i,
S1 = _context.SeatBooking.Count(j => j.Session == i && j.S1 == 1),
S2 = _context.SeatBooking.Count(j => j.Session == i && j.S2 == 1),
}
).OrderByDescending(s => s.Session).ToList();
由于列的类型是 bool
,首先要做的是将 bool
转换为 int
。
Func<bool, int> convertBoolToInt = flag => flag ? 1 : 0;
var query = _context.SeatBooking
.Select(s => new SeatBookingDto
{
SeatDate = s.SeatDate,
S1 = convertBoolToInt(s.S1),
S2 = convertBoolToInt(s.S2),
S3 = convertBoolToInt(s.S3),
S4 = convertBoolToInt(s.S4),
S5 = convertBoolToInt(s.S5),
S6 = convertBoolToInt(s.S6),
S7 = convertBoolToInt(s.S7),
});
现在我们可以分组并计算每组每列的总和:
query.GroupBy(m => m.SeatDate, m => m, (k, g) => new
{
Date = k,
S1= g.Sum(m=>m.S1),
S2= g.Sum(m=>m.S2),
S3= g.Sum(m=>m.S3),
S4= g.Sum(m=>m.S4),
S5= g.Sum(m=>m.S5),
S6= g.Sum(m=>m.S6),
S7= g.Sum(m=>m.S7),
})
如果您使用的是 EFCore,则相应的查询和结果为:
App> SELECT [s].[SeatDate], [s].[S1], [s].[S2], [s].[S3], [s].[S4], [s].[S5], [s].[S6], [s].[S7]
App> FROM [SeatBooking] AS [s]
App> ORDER BY [s].[SeatDate]
App> 1/1/2019 12:00:00 AM : 1,1,2,2,2,1,2
App> 2/1/2019 12:00:00 AM : 0,1,2,2,2,2,2
注意这里的 LINQ 表达式 g.sum()
都是在本地求值的,这意味着不由数据库求值。 EFcore 似乎还没有进化到能够将 Aggregate
表达式(例如 Sum
)转换为可以在服务器上执行的 SQL 查询。
如果你只想查询内存中的对象,还有另一种方法可以做到这一点(EFCore 尚不支持):
query.GroupBy(m=>m.SeatDate,m=>m,(k,g)=>new {
Date = k,
Count = g.Aggregate((c,n)=>new SeatBookingDto{
SeatDate=c.SeatDate,
S1=c.S1+n.S1,
S2=c.S2+n.S2,
S3=c.S3+n.S3,
S4=c.S4+n.S4,
S5=c.S5+n.S5,
S6=c.S6+n.S6,
S7=c.S7+n.S7,
})
})
谢谢大家, 只是一个快速更新,这似乎对我有用,但它很笨重
ViewData["CountSessions"] = _context.SeatBooking
// .Where(s => s.StudentEmail == _userManager.GetUserId(User))
.GroupBy(d => d.SeatDate)
.Select(s => new
{
SumS1 = s.Count(c => c.S1 == true),
SumS2 = s.Count(c => c.S2 == true),
SumS3 = s.Count(c => c.S3 == true),
SumS4 = s.Count(c => c.S4 == true),
SumS5 = s.Count(c => c.S5 == true),
SumS6 = s.Count(c => c.S6 == true),
SumS7 = s.Count(c => c.S7 == true),
SumS8 = s.Count(c => c.S8 == true),
SumS9 = s.Count(c => c.S9 == true),
SumS10 = s.Count(c => c.S10 == true)
}).ToListAsync();