У меня есть следующий запрос EF, который отлично работает. Обратите внимание, что я только что обнаружил, что могу напрямую фильтровать ссылочное свойство навигации.
context.AlertDetailsDbSet
.Where(ad => ad.Alert.CompanyId == companyId && ad.TrackedVehicule.RowEnabled == true)
// A limit is applied on returned elements
.Take(1000)
.OrderByDescending(ad => ad.AlertDateTime)
Я хотел бы включить свойство навигационной ссылки TrackedVehicule. Поэтому я наивно добавил предложение .Include:
context.AlertDetailsDbSet
.Include(ad => ad.TrackedVehicule)
.Where(ad => ad.Alert.CompanyId == companyId && ad.TrackedVehicule.RowEnabled == true)
// A limit is applied on returned elements
.Take(1000)
.OrderByDescending(ad => ad.AlertDateTime)
Но на этот раз запрос не удался с этим странным System.Data.SqlTypes.SqlNullValueException
at System.Data.SqlClient.SqlBuffer.get_Int64()
at System.Data.SqlClient.SqlDataReader.GetInt64(Int32 i)
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.<BufferlessMoveNext>d__12.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.<ExecuteAsync>d__7`2.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.<MoveNext>d__11.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.Internal.Lookup`2.<CreateForJoinAsync>d__16.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Lookup.cs:line 298
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.AsyncEnumerable.GroupJoinAsyncEnumerable`4.GroupJoinAsyncEnumerator.<MoveNext>d__8.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\GroupJoin.cs:line 153
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.AsyncEnumerable.SelectManyAsyncIterator`3.<MoveNextCore>d__12.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\SelectMany.cs:line 252
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.AsyncEnumerable.AsyncIterator`1.<MoveNext>d__10.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 112
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.<MoveNextCore>d__7.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.AsyncEnumerable.AsyncIterator`1.<MoveNext>d__10.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 109
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Linq.AsyncEnumerable.<Aggregate_>d__6`3.MoveNext() in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 120
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at RTE.Technologies.SafeProtect.Common.Data.DataBridge.Core.AlertDetailDataBridge.<GetAlertDetailAsync>d__2.MoveNext() in C:\Users\olivier.matrot\source\repos\SafeProtect\SafeProtect.Common\SafeProtect.Common.Data\DataBridge\Core\AlertDetailDataBridge.cs:line 86
Любая помощь приветствуется.
РЕДАКТИРОВАТЬ 1 : первый работающий запрос генерирует следующий SQL:
exec sp_executesql N'SELECT [t].[AlertDetailID], [t].[AckMachineName], [t].[AckPhoneNumber], [t].[AckTime], [t].[AckUserName], [t].[AlertDateTime], [t].[AlertID], [t].[AlertedCorridorId], [t].[AlertedItemId], [t].[AssociatedVehiculeID], [t].[AssociatedVehiculeUserID], [t].[Context], [t].[CustomID], [t].[CustomInfo], [t].[DbInsertTime], [t].[IsFleetAlert], [t].[MessageStatus], [t].[ReceivedTime], [t].[RowVersion], [t].[SafeProtectCustomInfo], [t].[TrackedVehiculeID], [t].[TrackedVehiculeUserID]
FROM (
SELECT TOP(@__p_1) [ad].[AlertDetailID], [ad].[AckMachineName], [ad].[AckPhoneNumber], [ad].[AckTime], [ad].[AckUserName], [ad].[AlertDateTime], [ad].[AlertID], [ad].[AlertedCorridorId], [ad].[AlertedItemId], [ad].[AssociatedVehiculeID], [ad].[AssociatedVehiculeUserID], [ad].[Context], [ad].[CustomID], [ad].[CustomInfo], [ad].[DbInsertTime], [ad].[IsFleetAlert], [ad].[MessageStatus], [ad].[ReceivedTime], [ad].[RowVersion], [ad].[SafeProtectCustomInfo], [ad].[TrackedVehiculeID], [ad].[TrackedVehiculeUserID]
FROM [AlertDetail] AS [ad]
LEFT JOIN [Vehicule] AS [ad.TrackedVehicule] ON [ad].[TrackedVehiculeID] = [ad.TrackedVehicule].[VehiculeID]
INNER JOIN [Alert] AS [ad.Alert] ON [ad].[AlertID] = [ad.Alert].[AlertID]
WHERE ([ad.Alert].[CompanyID] = @__companyId_0) AND ([ad.TrackedVehicule].[RowEnabled] = 1)
) AS [t]
ORDER BY [t].[AlertDateTime] DESC',N'@__p_1 int,@__companyId_0 int',@__p_1=1000,@__companyId_0=1
РЕДАКТИРОВАТЬ 2 : результат добавлениявызов Включить включает следующий второй запрос:
SELECT [ad.TrackedVehicule0].[VehiculeID], [ad.TrackedVehicule0].[Address], [ad.TrackedVehicule0].[AddressProtocol], [ad.TrackedVehicule0].[BoardID], [ad.TrackedVehicule0].[Category], [ad.TrackedVehicule0].[CompanyID], [ad.TrackedVehicule0].[CustomId], [ad.TrackedVehicule0].[DbInsertTime], [ad.TrackedVehicule0].[Description], [ad.TrackedVehicule0].[GpsBoxTrackingDelay], [ad.TrackedVehicule0].[GpsBoxType], [ad.TrackedVehicule0].[HardwareID], [ad.TrackedVehicule0].[HasGeoWorker], [ad.TrackedVehicule0].[IconID], [ad.TrackedVehicule0].[Name], [ad.TrackedVehicule0].[PhoneNumber], [ad.TrackedVehicule0].[RowEnabled], [ad.TrackedVehicule0].[RowVersion], [ad.TrackedVehicule0].[VehiculeUserID]
FROM [Vehicule] AS [ad.TrackedVehicule0]
Обработка этого дополнительного результирующего набора, кажется, беспокоит EF. Кроме того, этот выбор извлекает весь контент из таблицы, что может привести к ужасной производительности.