[英]Converting from EF 6 to EF Core, existing query throwing "given key was not present in the dictionary"
我正在將我們的一個 .NET Framework 應用程序從 EF 6 轉換為 EF Core (3.1.26)。 我們的一個查詢現在拋出一個KeyNotFoundException
。
此處顯示有問題的查詢:
var data = context.Applications
.Select(a => new
{
a.Id,
Attempt = a.Attempts
.Select(fa => new
{
fa.CandidateSubmissionReceivedDateUtc,
fa.FingerprintScores
})
.FirstOrDefault()
})
.SingleOrDefault(a => a.Id == request.ApplicationId);
如果我刪除fa.FingerprintScores
查詢執行得很好。 使用結果集中的該屬性,查詢將引發KeyNotFoundException
。 它是Attempts
實體上的一個集合屬性,定義如下:
private List<FingerprintScore> _fingerprintScores;
public List<FingerprintScore> FingerprintScores =>
_fingerprintScores = _fingerprintScores ?? new List<FingerprintScore>();
使用 SQL Server Profiler 永遠不會顯示訪問數據庫的請求,所以我假設它正在嘗試構建表達式樹,而不是與它試圖檢索的數據相關的東西。
現在我已經通過第二次查詢來獲取分數信息解決了這個問題,但是我們在整個代碼庫中都在做這種事情,所以我想更好地了解出了什么問題。
更新
使用 LINQPad 嘗試不同的組合我發現刪除fa.FingerprintScores或fa.FingerprintScores
.FirstOrDefault()
會導致查詢工作。 我可以在具有相同類型關系的任何查詢中一致地重現該行為。
正如評論中有人問的那樣,這里是堆棧跟蹤。
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ShaperRemappingExpressionVisitor.GetProjectionIndex(ProjectionBindingExpression projectionBindingExpression)
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ShaperRemappingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.CollectionShaperExpression.VisitChildren(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ShaperRemappingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitNew(NewExpression node)
at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitNew(NewExpression newExpression)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.IEnumerable.GetEnumerator()
at LINQPad.UI.ExplorerGrid.ConvertToList(IEnumerable source)
at LINQPad.UI.ExplorerGrid.UpdateDataSourceToUse()
嘗試以下查詢。 它強制 EF Core 使用不同的翻譯算法,但給出相同的結果。
var query =
from a in context.Applications
from fa in a.Attempts
.Select(fa => new
{
fa.CandidateSubmissionReceivedDateUtc,
fa.FingerprintScores
})
.Take(1)
.DefaultIfEmpty()
select new
{
a.Id,
Attempt = fa
};
var data = query
.SingleOrDefault(a => a.Id == request.ApplicationId);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.