C# EF Core 3.1在组合join和group by时意外生成SQL
我有一段C#代码(使用EF Core 3.1)执行SQL左连接操作C# EF Core 3.1在组合join和group by时意外生成SQL,c#,sql-server,entity-framework-core,ef-core-3.1,C#,Sql Server,Entity Framework Core,Ef Core 3.1,我有一段C#代码(使用EF Core 3.1)执行SQL左连接操作 var groupedQuery = query.GroupBy(x => x.CreatedTime.Date) .Select(o => new { Date = o.Key, Count = o.Count() }); var acceptedGroupedQuery = query.Where(o => o.Accepted).GroupBy(x
var groupedQuery = query.GroupBy(x => x.CreatedTime.Date)
.Select(o => new
{
Date = o.Key,
Count = o.Count()
});
var acceptedGroupedQuery = query.Where(o => o.Accepted).GroupBy(x => x.CreatedTime.Date)
.Select(o => new
{
Date = o.Key,
Count = o.Count()
});
var projectedQuery = groupedQuery.GroupJoin(acceptedGroupedQuery, o => o.Date, i => i.Date,
(o, i) => new { Total = o, Accepted = i })
.SelectMany(o => o.Accepted.DefaultIfEmpty(), (joined, accepted) => new
{
Date = joined.Total.Date,
Total = joined.Total.Count,
Accepted = accepted.Count
});
var result = await projectedQuery
.Skip(model.Skip).Take(model.Take).ToArrayAsync(cancellationToken: cancellationToken);
相应的SQL生成是
exec sp_executesql N'SELECT [t].[c] AS [Date], CAST([t].[c0] AS float) AS [Total], CAST([t0].[c0] AS float) AS [Accepted]
FROM (
SELECT CONVERT(date, [p].[CreatedTime]) AS [c], COUNT(*) AS [c0]
FROM [PartnerInvitation] AS [p]
WHERE [p].[DeletedTime] IS NULL
GROUP BY CONVERT(date, [p].[CreatedTime])
) AS [t]
LEFT JOIN (
SELECT CONVERT(date, [p0].[CreatedTime]) AS [c], [t].[c0]
FROM [PartnerInvitation] AS [p0]
WHERE [p0].[Accepted] = 1
GROUP BY CONVERT(date, [p0].[CreatedTime])
) AS [t0] ON [t].[c] = [t0].[c]
ORDER BY (SELECT 1)
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__p_0 int,@__p_1 int',@__p_0=0,@__p_1=10
上述查询给出了以下错误:
味精4104,16级,状态1,第9行。无法绑定多部分标识符“t.c0”
我希望左联接中的第二个select语句是select…,将(*)计数为[c0],而不是select…,t.[c0]
你知道这里发生了什么,怎么解决吗
知道这里发生了什么吗
显然,EF Core 3.x错误-在EF Core 5.x中,相同的查询得到了预期的正确翻译
如何解决
修复库bug基本上是不可能的。好的是它是固定的,坏的是它是在v5.x中固定的,而不是在v3.1中-它出现在最新的v3.1.14版本中,而且由于他们已经在v6.0上工作,我认为它永远不会在v3.1中固定
因此,一个选择是升级到最新的v5.x
另一个选项,但仅针对此特定查询,是以不使用联接的方式重写它-它可以通过单个GroupBy
查询和条件Sum
(在v5.x中,您也可以使用条件Count
)轻松高效地实现,例如,摆脱groupedQuery
和acceptedGroupedQuery
,只需这样做
var projectedQuery = query
.GroupBy(e => e.CreatedTime.Date)
.Select(g => new
{
Date = g.Key,
Total = g.Count(),
Accepted = g.Sum(e => e.Accepted ? 1 : 0)
});
似乎是一个bugI在EF Core回购中发布了一个问题:@TrầnNamTrung因为它已经被修复(见我的答案),他们应该知道它,所以发布一个新的问题不会有帮助-很可能它会作为某个东西的副本关闭。