Навигационные свойства классов равны 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.

Здесь можно увидеть сущность Book в json и тут отчётливо видно, что все навигационные свойства равны null


Ответы (0 шт):