#c# #entity-framework-core #lazy-loading
#c# #entity-framework-core #отложенная загрузка
Вопрос:
Я использую ядро EF, и у меня проблема с отложенной загрузкой.
Моя модель:
public class Product
{
public int Id{get; set;}
public string Name {get; set;}
public virtual Category Category {get; set;}
}
public class Category
{
public int Id{get; set;}
public string Name {get; set;}
}
Код для извлечения продуктов:
List<int> selectedCategories = new List<int> { 1, 2 };
// DatabaseContext inherited from DbContext
// Products is of type DbSet<Product>
IQueryable<Product> query = _dbContext.Products.Include(p=>p.Category);
IQueryable<Product> filtered = query.Where(p => selectedCategories.Contains(p.Category.Id));
var result = filtered.ToList();
Проблема filtered
в том, что список содержит действительно отфильтрованные по идентификаторам категории продукты, но категория равна нулю для всех продуктов. Поэтому, когда я передаю этот результат для просмотра и пытаюсь получить имя категории, у меня возникает исключение с нулевой ссылкой.
Как я могу загрузить сущность категории с помощью Product?
UPD: уже решено!
Я понял, что использую неправильный .Include
метод from System.Data.Entity
вместо Microsoft.EntityFrameworkCore
.
Итак, если вы столкнулись с той же проблемой, проверьте, используете ли вы правильный метод расширения из Microsoft.EntityFrameworkCore
.
Комментарии:
1. Ах, я вижу, вы уже решили свою проблему. Пожалуйста, отправьте правильный «ответ», используя кнопку ответа, чтобы каждый читатель мог ясно видеть, что эта проблема решена.
2. Ваша проблема не может быть решена без исправления класса, поскольку в вашем EF есть ошибки
Ответ №1:
Я понял, что использую неправильный .Include
метод from System.Data.Entity
вместо Microsoft.EntityFrameworkCore
.
Итак, если вы столкнулись с той же проблемой, проверьте, используете ли вы правильный метод расширения из Microsoft.EntityFrameworkCore
.
Комментарии:
1. Он будет работать как плохой пример в памяти компьютера, но вы не сможете сохранить его в БД
2. Продукт должен иметь внешний ключ CategoryID для обеспечения связи между двумя классами.
3. @Sergey Как вы можете видеть, я использовал неправильный метод включения. Я пытался добавить CategoryID, но это не помогло. Также я должен сказать, что сохранение объекта в БД не связано с этим сообщением. Итак, вы правы, мне нужен CategoryID, если я хочу сохранить эту модель, но это не решение описанной проблемы.
4. Даже если ваше решение предназначено для обучения и не будет работать в реальном контексте EF, это не лучшее решение. Вам не нужны два запроса. Достаточно одного запроса.
5. @Sergey Как я уже сказал, это всего лишь пример, созданный для четкого понимания. Реальная модель и фильтрация намного сложнее.
Ответ №2:
Вы можете использовать этот код
var filtered = _dbContext.Products
.Include(p => p.Category) // maybe you don't need this
.Where(p => selectedCategories.Contains(p.CategoryId))
.ToList();
Но в вашем продукте есть ошибка. Он должен иметь внешний ключ CategoryID, чтобы обеспечить связь между двумя классами.
public class Product
{
public int Id { get; set; }
public int CategoryId { get; set; }
public string Name { get; set; }
public virtual Category Category { get; set; }
}
Комментарии:
1. Нет, этого не должно быть. В любом случае это всего лишь пример, и это не имеет значения. Проверьте последнее обновление поста.
2. Он будет работать как плохой пример в памяти компьютера, но вы не сможете сохранить его в БД