Сложный запрос ef core 2.1 создает исключение с нулевой ссылкой, как мы находим причину проблемы

У меня сложный запрос, который дает исключение для нулевой ссылки: «Ссылка на объект не установлена ​​на экземпляр объекта».

Примером сложного запроса может быть производитель автомобилей, который должен доставить автомобили в автосалон в определенный день. Итак, у нас есть машина:

public class Car

{public int CarId {получить; установленный; }

    public string Model { get; set; }
    public string Color { get; set; }

    public int? CarActionDefId { get; set; }

    public CarActionDef CarActionDef { get; set; }

}

общедоступный класс ActionDef {общедоступный int ActionDefId {получить; установленный; }

public string Name { get; set; }

public List<ActionSchedules> ActionSchedules { get; set; }

}

общедоступный класс CarActionDef {общедоступный int CarActionDefId {получить; установленный; }

public int CarId { get; set; }

public int ActionDefId { get; set; }

public Car Car { get; set; }

public ActionDef ActionDef { get; set; }

}

открытый класс ActionSchedule {общедоступный int ActionScheduleId {получить; установленный; }

public DateTime? NextDue { get; set }

public int ActionDef_RID { get; set }

public virtual ActionDef ActionDef { get; set }

}

Поймите, что это псевдокод, чтобы дать вам представление о том, что происходит. Если мы хотим получить автомобили, поставка которых запланирована между датой начала и датой окончания, мы используем такой запрос:

            res =
                context.Cars.
                    Include ( g => CarActionDef ).
                    Include ( g => g.CarActionDef.ActionDef ).
                    Include ( g => g.CarActionDef.ActionDef.ActionSchedules ).
                    Where ( g => g.CarActionDef != null && g.CarActionDef.ActionDef != null &&
                                 g.CarActionDef.ActionDef.ActionSchedules != null &&
                                 g.CarActionDef.ActionDef.ActionSchedules.Count > 0 ).
                    Where ( g => g.CarActionDef.ActionDef.ActionSchedules [ 0 ].NextDue != null &&
                                 g.CarActionDef.ActionDef.ActionSchedules [ 0 ].NextDue >= startDate &&
                                 g.CarActionDef.ActionDef.ActionSchedules [ 0 ].NextDue <= endDate ).
                    OrderByDescending ( g => g.CarActionDef.ActionSchedules [ 0 ].NextDue ).
                    Select ( g => g ).
                    ToList ();

Однако, когда мы выполняем этот оператор, мы получаем исключение с нулевой ссылкой. Мы протестировали метод получения любого CarActionDef для автомобиля с нулевым значением, и мы получили пустую коллекцию. Точно так же мы попробовали CarActionDef.ActionDef и CarActionDef.ActionDef.ActionSchedules, и обе возвращенные коллекции были пустыми. Таким образом, отладка для поиска проблемного свойства навигации или списка ничего не дала, и нет внутреннего исключения. Есть ли способ найти причину исключения нулевой ссылки?


person dgxhubbard    schedule 17.09.2019    source источник
comment
Проверьте предупреждения об оценке клиента. Скорее всего, индексатор (ActionSchedules [ 0 ]) вызывает оценку клиента, и в это время свойства навигации еще не загружены (хотя они будут позже при применении Includes). Оценка клиента в любом случае не будет поддерживаться в EF Core 3.0, поэтому попробуйте переписать запрос без использования индексатора или вставьте .AsEnumerable() перед вторым .Where, чтобы принудительно переключиться на контекст LINQ to Objects.   -  person Ivan Stoev    schedule 17.09.2019


Ответы (1)


Вы можете использовать затем включить

`res =  context.Cars.Include ( g => CarActionDef )
.ThenInclude ( f => f.ActionDef )
.ThenInclude ( t => t.ActionSchedules )`
person David Edel    schedule 17.09.2019
comment
Я не уверен, как это поможет. У нас есть такие же включения в других операторах, использующих те же включения, и все работает. Единственное отличие - это выражение where - person dgxhubbard; 17.09.2019