Навигационные свойства классов равны null в EF Core
Я использую ORM Entity Framework Core и подход Code First. Моя цель - моделирование библиотеки. Есть 3 сущности: автор, категория и книга.
Класс автора:
public class Author
{
// Свойства класса.
public int Id { get; set; } // Идентификатор.
public string AuthorName { get; set; } // Имя автора.
public virtual ICollection<Book> Books { get; set; } // Книги.
// Ансамбль конструкторов.
// Конструктор по умолчанию.
public Author() { }
// Конструктор с параметрами.
public Author(string authorName)
{
AuthorName = authorName;
} // ctorf.
} // Author.
Класс категории:
public class Category
{
// Свойства класса.
public int Id { get; set; } // Идентификатор.
public string CategoryName { get; set; } // Название категории.
public virtual ICollection<Book> Books { get; set; } // Книги.
// Ансамбль конструкторов.
// Конструктор по умолчанию.
public Category() { }
// Конструктор с параметрами.
public Category(string categoryName)
{
CategoryName = categoryName;
} // ctorf.
} // Category.
Класс книги:
public class Book
{
// Свойства класса.
public int Id { get; set; } // Идентификатор.
public string Title { get; set; } // Название.
public int YearOfIssue { get; set; } // Год выпуска.
public int Price { get; set; } // Цена.
public int Amount { get; set; } // Количество.
public int AuthorId { get; set; } // Внешний ключ автора.
public virtual Author Author { get; set; } // Автор.
public int CategoryId { get; set; } // Внешний ключ категории
public virtual Category Category { get; set; } // Категория.
// Ансамбль конструкторов.
// Конструктор по умолчанию.
public Book() { }
// Конструктор с параметрами.
public Book(string title, int yearOfIssue, int price, int amount)
{
Title = title;
YearOfIssue = yearOfIssue;
Price = price;
Amount = amount;
} // ctorf.
} // Book.
Также у меня есть такой класс DbContext, а в методе OnModelCreating прописаны отношения между сущностями и заполнение ими базы данных.
public sealed class LibraryDbContext : DbContext
{
// Таблицы БД.
public DbSet<Author> Authors { get; set; } // Авторы.
public DbSet<Category> Categories { get; set; } // Категории.
public DbSet<Book> Books { get; set; } // Книги.
#region Ансамбль конструкторов
// Ансамбль конструкторов.
// Конструктор по умолчанию.
public LibraryDbContext() { }
// Конструктор с параметрами.
public LibraryDbContext(DbContextOptions<LibraryDbContext> options) : base(options)
{
// Чтобы вызвать этот метод в конструкторе, Intellisense посоветовал
// Сделать запечатать класс (sealed).
// TODO: Убрать при готовом проекте Database.EnsureDeleted().
Database.EnsureDeleted();
Database.EnsureCreated();
} // ctorf.
#endregion
// Методы класса.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region Настройка связей "один-ко-многим"
// Настройка связей "один-ко-многим".
modelBuilder.Entity<Book>()
.HasOne(p => p.Category)
.WithMany(p => p.Books)
.HasForeignKey(p => p.CategoryId);
modelBuilder.Entity<Book>()
.HasOne(p => p.Author)
.WithMany(p => p.Books)
.HasForeignKey(p => p.AuthorId);
// Настройка навигационных свойств.
modelBuilder.Entity<Author>()
.Navigation(p => p.Books)
.UsePropertyAccessMode(PropertyAccessMode.Property);
modelBuilder.Entity<Category>()
.Navigation(p => p.Books)
.UsePropertyAccessMode(PropertyAccessMode.Property);
#endregion
// Настройка сущности Category.
modelBuilder.Entity<Category>()
.Property(p => p.CategoryName)
.IsUnicode()
.IsRequired();
// Настройка сущности Author.
modelBuilder.Entity<Author>()
.Property(p => p.AuthorName)
.IsUnicode()
.IsRequired();
#region Настройка сущности Book
// Настройка сущности Book.
modelBuilder.Entity<Book>()
.Property(p => p.Title)
.IsUnicode()
.IsRequired();
modelBuilder.Entity<Book>()
.Property(p => p.YearOfIssue)
.IsRequired();
modelBuilder.Entity<Book>()
.Property(p => p.Price)
.IsRequired();
modelBuilder.Entity<Book>()
.Property(p => p.Amount)
.IsRequired();
#endregion
#region Подготовка данных для инициализации БД
// Подготовка данных для инициализации БД.
// Категории.
var categories = new[]
{
new Category("Роман"){Id = 1},
new Category("Детектив"){Id = 2},
new Category("Рассказ"){Id = 3},
new Category("Повесть"){Id = 4}
}; // categories.
// Авторы.
var authors = new[]
{
new Author("Л.Н. Толстой"){Id = 1},
new Author("А.С. Пушкин"){Id = 2},
new Author("А.П. Чехов"){Id = 3},
new Author("С.А. Есенин"){Id = 4}
}; // authors.
// Книги.
var books = new[]
{
new Book("Война и мир", 1987, 200, 10){Id = 1, AuthorId = 1, CategoryId = 1},
new Book("Детство", 1852, 150, 15){Id = 2, AuthorId = 1, CategoryId = 3},
new Book("Капитанская дочка", 1836, 350, 20){Id = 3, AuthorId = 2, CategoryId = 1},
new Book("Пиковая дама", 1823, 100, 8){Id = 4, AuthorId = 2, CategoryId = 3},
new Book("Палата № 6", 1900, 250, 12){Id = 5, AuthorId = 3, CategoryId = 4},
new Book("Студент", 1912, 300, 15){Id = 6, AuthorId = 3, CategoryId = 4},
new Book("Чёрный человек", 1926, 500, 18){Id = 7, AuthorId = 4, CategoryId = 2},
new Book("Анна Снегина", 1925, 200, 15){Id = 8, AuthorId = 4, CategoryId = 2}
};
#endregion
// Записываем данные в БД.
modelBuilder.Entity<Category>().HasData(categories);
modelBuilder.Entity<Author>().HasData(authors);
modelBuilder.Entity<Book>().HasData(books);
} // OnModelCreating.
} // LibraryDbContext.
