Как отладить и исправить 'Nullable объект должен иметь значение' в Entity Framework Core? - PullRequest
0 голосов
/ 22 января 2020

В этом методе выполняется проекция:

public async Task<TradeDetail> Get(int tradeId)
{
    var firstOrDefaultAsync = await context.EvgTGTrade
        .Where(x => x.IdTrade == tradeId)
        .Select(trade => new TradeDetail
        {
            Id = trade.IdTrade,
            Code = trade.CdTrade,
            Description = trade.DeTrade,
            Comments = trade.DeComentarios,
            TypeId = trade.IdTipoTrade,
            BrokerId = trade.EvgTGBrokerTrade.FirstOrDefault().IdBroker,
            BillingCycleId = trade.IdCicloFacturacion,
            CounterpartId = trade.IdSujeto,
            StartDate = trade.FhIni,
            EndDate = trade.FhFin,
            SignatureDate = trade.FhFirma,
            Positions = trade.EvgTGPosicion.Select(pos => new Position
            {
                Amount = pos.Cantidad,
                Code = pos.CdPosicion,
                Description = pos.DePosicion,
                LogisticElement = pos.IdElemLogNavigation.DeElemLog,
                StartDate = pos.FhIni,
                EndDate = pos.FhFin,
                FormulaId = pos.IdFormula,
                Operations = pos.EvgTGOperacionCv.Select(op =>
                    new Operation()
                    {
                        TypeId = op.IdTipoOperacion,
                        Fee = op.Fee,
                        Date = op.FhOperacionCv,
                        Price = op.NmPrecio ?? 0,
                        Quantity = op.NmCantidadKwh ?? 0,
                    }),
            })
        })
        .FirstOrDefaultAsync();
    return firstOrDefaultAsync;
}

В первой строке я получаю исключение, сообщающее

Microsoft.EntityFrameworkCore.Query: Ошибка: Возникла исключительная ситуация при переборе результатов запроса для типа контекста 'SampleApp.EF.MyDbContext'. System.InvalidOperationException: Nullable-объект должен иметь значение.

Я проверил исключение и трассировку стека, и он ничего не говорит о том, что является проблемным c объектом. Понятия не имею, что не так.

Итак, есть ли способ узнать, какое свойство порождает конфликт? Я уверен, что это несоответствие столбца свойств, но что, если у вас много свойств? Это довольно больно!

Обновление

Я уже исправил проблему. Я был из-за попытки присвоить значение null свойству в моей модели, которое не могло быть обнулено.

Тем не менее, этот вопрос не об этом конкретном исправлении, а о поиске общего способа отладки такого рода ситуаций (это исключение), которые довольно распространены. ИМХО, сообщение об исключении слишком расплывчато. Он не предоставляет полезной информации о конфликтующем свойстве.

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Может быть два ответа.

Во-первых, , возможно, это связано с тем, что ваш запрос возвращает NULL, а модель не принимает ноль.

Второе исправление может быть , если вы используете анонимные типы, попробуйте типизировать результат запроса в обнуляемый тип.

например

Id = (int?) op.Id,

как узнать, какое свойство возвращает NULL?

Вы можете включить SQL Profiler и проверить запрос SQL, который выполняется. Скопируйте запрос в SSMS и посмотрите, какие значения имеют значение NULL.
Это может быть полезно для вас, чтобы решить, действительно ли вам нужен тип с типом nullable ИЛИ вы хотите изменить сам запрос.

Возникла проблема с GitHub на этой странице .

0 голосов
/ 22 января 2020

Насколько я знаю, обычно не существует более быстрого способа определить, что именно является полем, из-за которого возникает проблема.

Что вы можете сделать, глядя на ваше дело, так это:

1 - посмотрите запрос, который вы делаете, и убедитесь, что он возвращает необходимые данные. Если это происходит хорошо, то, вероятно, запрос может вернуть ноль, и ваша модель не принимает это (и наоборот).

2 - Если первый элемент работает правильно, попробуйте посмотреть на другие итерации, которые вы делаете на модели. Например: вы выполняете Positions.Select (), поэтому проверьте, все ли позиции и другие вещи, исходящие из модели позиций, все в порядке.

3 - Если вы не уверены на сто процентов в том, что это поле. Просто установите обнуляемый тип для каждого поля, которое вы делаете linq. Пример: BrokerId = trade.EvgTGBrokerTrade.FirstOrDefault (). IdBroker, вы можете добавить знак вопроса, чтобы убедиться, что поле не будет обрабатывать sh ваше приложение.

4 - посмотрите таблицы, которые вы создаете в базе данных, вероятно, она будет иметь информацию о полях, если они обнуляемы или нет. Затем вы можете изменить свою модель кода.

Это то, что я предлагаю вам

...