EF Core 3 GroupBy 多列 Count Throws with extensions 但 linq 有效
EF Core 3 GroupBy multiple columns Count Throws with extensions but linq works
这是抛出完整异常的那个:
var duplicateCountOriginal = _db.TableName
.GroupBy(g => new {g.ColumnA, g.ColumnB, g.ColumnC})
.Count(g => g.Count() > 1);
异常:
System.ArgumentException:'System.Func2[System.Linq.IGrouping
2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer],Microsoft.EntityFrameworkCore.Storage.ValueBuffer]'类型的表达式不能用于'System.Func2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer]' of method 'System.Collections.Generic.IEnumerable
1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer] Select[ValueBuffer,ValueBuffer](System.Collections.Generic.IEnumerable1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer], System.Func
2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer])'类型的参数(参数'arg1')
但是当它被写成 linq 时同样有效(我更喜欢扩展)
var duplicateCount =
from a in _db.TableName
group a by new {a.ColumnA, a.ColumnB, a.ColumnC}
into g
where g.Count() > 1
select g.Key;
duplicateCount.Count()
我无法理解为什么一个有效而另一个无效。
此外,如果我根据 EF Core 3 更改第一个,如下所示
var duplicateCountOriginal = _db.TableName
.GroupBy(g => new {g.ColumnA, g.ColumnB, g.ColumnC})
.AsEnumerable()
.Count(g => g.Count() > 1);
我得到以下 异常:
System.InvalidOperationException:客户端投影包含对作为参数传递给方法 'TryReadValue' 的 'Microsoft.EntityFrameworkCore.Metadata.IPropertyBase' 常量表达式的引用。这可能会导致内存泄漏。考虑将此常量分配给局部变量并改为在查询中使用该变量。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2103067。
在我看来,ms给的link对这里的问题没有任何意义。
如果有合理的解释请LMK
没有合乎逻辑的解释。仅 EF Core 查询翻译仍远非完美,并且有许多 defects/bugs/unhandled 个案例。
在这个特定的问题中,问题不在于查询语法或方法语法(你称之为扩展),而是在 GroupBy
之后缺少 Select
。如果您重写类似于使用查询语法的方法语法查询,即添加 .Where
、.Select
然后 Count
:
var duplicateCount = _db.TableName
.GroupBy(g => new {g.ColumnA, g.ColumnB, g.ColumnC})
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.Count();
那么就编译执行成功了
这是抛出完整异常的那个:
var duplicateCountOriginal = _db.TableName
.GroupBy(g => new {g.ColumnA, g.ColumnB, g.ColumnC})
.Count(g => g.Count() > 1);
异常:
System.ArgumentException:'System.Func2[System.Linq.IGrouping
2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer],Microsoft.EntityFrameworkCore.Storage.ValueBuffer]'类型的表达式不能用于'System.Func2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer]' of method 'System.Collections.Generic.IEnumerable
1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer] Select[ValueBuffer,ValueBuffer](System.Collections.Generic.IEnumerable1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer], System.Func
2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer])'类型的参数(参数'arg1')
但是当它被写成 linq 时同样有效(我更喜欢扩展)
var duplicateCount =
from a in _db.TableName
group a by new {a.ColumnA, a.ColumnB, a.ColumnC}
into g
where g.Count() > 1
select g.Key;
duplicateCount.Count()
我无法理解为什么一个有效而另一个无效。 此外,如果我根据 EF Core 3 更改第一个,如下所示
var duplicateCountOriginal = _db.TableName
.GroupBy(g => new {g.ColumnA, g.ColumnB, g.ColumnC})
.AsEnumerable()
.Count(g => g.Count() > 1);
我得到以下 异常: System.InvalidOperationException:客户端投影包含对作为参数传递给方法 'TryReadValue' 的 'Microsoft.EntityFrameworkCore.Metadata.IPropertyBase' 常量表达式的引用。这可能会导致内存泄漏。考虑将此常量分配给局部变量并改为在查询中使用该变量。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2103067。
在我看来,ms给的link对这里的问题没有任何意义。
如果有合理的解释请LMK
没有合乎逻辑的解释。仅 EF Core 查询翻译仍远非完美,并且有许多 defects/bugs/unhandled 个案例。
在这个特定的问题中,问题不在于查询语法或方法语法(你称之为扩展),而是在 GroupBy
之后缺少 Select
。如果您重写类似于使用查询语法的方法语法查询,即添加 .Where
、.Select
然后 Count
:
var duplicateCount = _db.TableName
.GroupBy(g => new {g.ColumnA, g.ColumnB, g.ColumnC})
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.Count();
那么就编译执行成功了