У меня есть следующий динамический LINQ, работающий без ошибок в .NET Core 3.1.
query = query.GroupJoin(ParsingConfig.DefaultEFCore21,
detailObject,
"new { it.ExternalDataId2.Value AS I0}",
"new { Id AS I0}",
"new (outer AS A, inner AS B)");
query = query.SelectMany("B.DefaultIfEmpty()",
"new { source.A.Id AS Id,source.A.ExternalDataId2 AS ExternalDataId2,detail.Title AS ExternalData2Ref_Title,detail.Id AS ExternalData2Ref_Id}",
"source",
"detail");
query.ToDynamicListAsync();
Я переношу свое приложение на .NET 6.0 и получаю эту ошибку: объект Nullable должен иметь значение.
Я попытался удалить «ParsingConfig», не решив проблему. Используя SQL Profiler, я увидел, что запрос выполняется.
Полная трассировка стека исключений:
Message:
Test method FrameworkTests.DataLayer.FindTests.FindValueExternal threw exception:
NTSFramework.DataLayer.DataLayerException: Errore generico di repository Nullable object must have a value.
---> System.InvalidOperationException: Nullable object must have a value.
Stack Trace:
lambda_method559(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
AsyncEnumerator.MoveNextAsync()
DynamicEnumerableAsyncExtensions.ToListAsync[T](IEnumerable source, CancellationToken cancellationToken)
DynamicEnumerableAsyncExtensions.ToListAsync[T](IEnumerable source, CancellationToken cancellationToken)
BaseDataLayer.FindValuesAsync[TModel](FindValuesOptions findOptions) line 866
Изменение SelectMany, как показано ниже, больше не вызывает ошибку, но это не тот результат, который мне нужен:
query = query.SelectMany("B.DefaultIfEmpty()",
"new { source.A.Id AS Id,source.A.ExternalDataId2 AS ExternalDataId2,detail As ExternalData2Ref}",
"source",
"detail");
Пробовал, не решает проблему. Я добавил дополнительную информацию. Проблема, кажется, в SelectMany.
Добавить стек вызовов исключений.
добавлен стек вызовов
ты пробовал , detail != null ? detail.Title : string.Empty AS ExternalData2Ref_Title, ...
Оно работает! Если вы напишете ответ, я приму его!
@PaoloCrociati: у меня нет под рукой Dynamic LINQ, можете ли вы попробовать функцию распространения нулей np()
? Вместо detail != null ? detail.Title : string.Empty
попробуйте np(detail.Title)
, пожалуйста.
@GWimpassinger Только что попробовал. Оно работает. Странно то, что с .NET Core 3.1 в этом не было необходимости.
Проблема возникает из-за вашего B.DefaultIfEmpty()
в вашем SelectMany
выражении. Если соединение не дает никаких B, ваша сущность detail
является null
, и вы не можете разыменовывать detail.Title
или detail.Id
.
Вы можете явно проверить значение null и вместо detail.Title
вы должны написать detail != null ? detail.Title : string.Empty AS ExternalData2Ref_Title
. Или вы можете использовать динамическую функцию распространения null LINQ np()
и написать np(detail.Title)
.
В вашем коде это должно выглядеть так (я предположил, что detail.Id
имеет тип int
):
query = query.SelectMany("B.DefaultIfEmpty()",
"new { source.A.Id AS Id,source.A.ExternalDataId2 AS ExternalDataId2, np(detail.Title) AS ExternalData2Ref_Title, detail != null ? detail.Id : 0 AS ExternalData2Ref_Id}",
"source",
"detail");
Это как-то связано с обнуляемыми свойствами, попробуйте удалить
.Value
изit.ExternalDataId2.Value