gpt4 book ai didi

linq - EFCore 2.2 GroupBy Sum 和 DateDiff

转载 作者:行者123 更新时间:2023-12-04 23:25:51 27 4
gpt4 key购买 nike

我正在尝试将以下 SQL 转换为 EF Core 查询,但我收到警告,将在本地评估 GroupBy 和 Sum。无论如何,目前是否可以编写此内容以将其完全转换为 SQL?

SELECT UserId, ST.StatusId, SUM(DATEDIFF(MINUTE, StartDate, ISNULL(EndDate,GETDATE()))) AS Time
FROM StatusTransaction ST
WHERE
TeamManagerId = 1
AND StartDate >= N'01-01-2019'
AND ISNULL(EndDate,GETDATE()) <= N'01-02-2019'
GROUP BY UserId, ST.StatusId
ORDER BY UserId

这些是我使用过的 EF 查询:
var efFunction = await context
.Where(st => st.TeamManagerId == tmId && st.StartDate >= dateFrom && (st.EndDate ?? DateTime.Now) <= dateTo)
.GroupBy(st => new { st.UserId, st.StatusId })
.Select(g => new
{
g.Key.UserId,
g.Key.StatusId,
Time = g.Sum(st => Microsoft.EntityFrameworkCore.EF.Functions.DateDiffMinute(st.StartDate, st.EndDate)) // null check not done on end date - (st.EndDate ?? DateTime.Now) causes an error here
}).ToListAsync(cancellationToken).ConfigureAwait(false);

var simpleDateSubtraction = await context
.Where(st => st.TeamManagerId == tmId && st.StartDate >= dateFrom && (st.EndDate ?? DateTime.Now) <= dateTo)
.GroupBy(st => new { st.UserId, st.StatusId })
.Select(g => new
{
g.Key.UserId,
g.Key.StatusId,
Time = g.Sum(st => st.EndDate.Value.Subtract(st.StartDate).Minutes)// null check not done on end date - (st.EndDate ?? DateTime.Now) causes an error here
}).ToListAsync(cancellationToken).ConfigureAwait(false);

var groupBySimpleSum = await context
.Where(st => st.TeamManagerId == tmId)
.GroupBy(st => new { st.TeamManagerId, st.OperationsManagerId })
.Select(g => new
{
g.Key.OperationsManagerId,
g.Key.TeamManagerId,
Foo = g.Sum(st => st.UserId) // nonsense but a simple column to sum, this translates fully to SQL
}).ToListAsync(cancellationToken).ConfigureAwait(false);

最佳答案

首先,EF Core 仍然不支持翻译 TimeSpan操作,和 DateTime差异产生TimeSpan ,因此 EF.Functions.DateDiff方法是正确的方法。

其次,它还可以翻译GroupBy仅在简单的成员访问器表达式上聚合。所以你必须预先Select GroupBy表达式:

var query = context
.Where(st => st.TeamManagerId == tmId
&& st.StartDate >= dateFrom
&& (st.EndDate ?? DateTime.Now) <= dateTo
)
.Select(st => new
{
st.UserId,
st.StatusId,
Time = EF.Functions.DateDiffMinute(st.StartDate, st.EndDate ?? DateTime.Now)
})
.GroupBy(st => new { st.UserId, st.StatusId })
.Select(g => new
{
g.Key.UserId,
g.Key.StatusId,
Time = g.Sum(st => st.Time)
});

或使用 GroupBy允许预先选择聚合源的重载:
var query = context
.Where(st => st.TeamManagerId == tmId
&& st.StartDate >= dateFrom
&& (st.EndDate ?? DateTime.Now) <= dateTo
)
.GroupBy(st => new { st.UserId, st.StatusId }, st => new
{
Time = EF.Functions.DateDiffMinute(st.StartDate, st.EndDate ?? DateTime.Now)
})
.Select(g => new
{
g.Key.UserId,
g.Key.StatusId,
Time = g.Sum(st => st.Time)
});

关于linq - EFCore 2.2 GroupBy Sum 和 DateDiff,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54670684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com