从网络框架转换到核心,这伴随着将实体框架 6 转移到 EFCore 7。
我配置了无钥匙视图:
modelBuilder.Entity<MySampleView>(entity =>
{
entity
.HasNoKey()
.ToView("MySampleView");
我的查询很简单,之前在 Framework 下使用 EF6 运行良好。过滤、分组、ToDictionary
var result = await context.MySampleView
.Where(x => ... SomeConditions)
.GroupBy(x => new { x.Column1, x.Column2, x.Column3 })
.ToDictionaryAsync(x => x.Key.Column1,
x => new { x.Key.Column2, x.Key.Column3, ... });
注意 - 这里不会有重复的键 - Column1,2,3 总是相同的
但是,这将引发来自 EF7 框架内的异常。
Value cannot be null. (Parameter 'collection')
堆栈跟踪将其放入 EFCore 源代码中:
System.ArgumentNullException
HResult=0x80004003
Message=Value cannot be null. (Parameter 'collection')
Source=System.Private.CoreLib
StackTrace:
at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) in /_/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs:line 284
对这里的屏幕截图表示歉意,因为出于某种原因,我似乎无法从 VS 以文本格式获取完整的堆栈跟踪。
深入研究符号源,我可以看到这种情况发生在哪里,但它不应该发生。
您可以看到它将这个可为空的
_preGroupByIdentifier
传递给了它。在这种情况下,为空。 (这是 MS 符号源)
MS 参考来源:SelectExpression 参考 1
我确认它不应该为空,但这很棘手。我不确定是否存在一些优化器问题,或者只是我的调试器在这里对我撒谎。
_preGroupByIdentifier
应在此处设置为空列表,但它完全被跳过,如下所示。这是来自 MS 符号源 - 请注意,对于其他查询,我发现它不会跳过第二个断点。这是怎么回事? 我认为如果不跳过此错误就不会发生此错误!
MS 参考来源:SelectExpression 参考 2
作为一种解决方法,这有效且没有错误,但将 GroupBy/Dictionary 放入标准 Linq/Entities 中。这不是正确的方法,因为投影应该由 SQL Server + EF 处理,而不是在 dotnet 应用程序的内存中成形。
var result = (await context.MySampleView
.Where(x => ... SomeConditions)
.ToListAsync()) // Running the ToListAsync first - not desirable
.GroupBy(x => new { x.Column1, x.Column2, x.Column3 })
.ToDictionaryAsync(x => x.Key.Column1,
x => new { x.Key.Column2, x.Key.Column3 });
帮助我找到我在这里缺少的东西。