Инициализация БД начальными данными

Последнее обновление: 04.02.2022

Иногда необходимо, чтобы при первом обращении база данных уже содержала некоторые данные. И Entity Framework Core позволяет инициализировать базу данных при ее создании некоторыми начальными данными. Благодаря этому к моменту первого использования базы данных она уже будет содержать начальные данные, которые мы сможем тут же использовать. И нам не потребуется вручную или программно добавлять в БД нужные нам данные.

Для инициализации БД при конфигурации определенной модели вызывается метод HasData(), в который передаются добавляемые данные:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	modelBuilder.Entity<User>().HasData( new User { Id=1, Name="Tom", Age=36});
}

Например, инициализируем БД набором данных:

using Microsoft.EntityFrameworkCore;

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public ApplicationContext()
    {
        Database.EnsureDeleted();
        Database.EnsureCreated();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=helloapp.db");
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasData(
                new User { Id = 1, Name = "Tom", Age = 23 },
                new User { Id = 2, Name = "Alice", Age = 26 },
                new User { Id = 3, Name = "Sam", Age = 28 }
        );
    }
}
public class User
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public int Age { get; set; }
}

У объекта ModelBuilder, который передается в OnModelCreating в качестве параметра, вызывается метод Entity<T>(). Этот метод типизируется типом, для которого будут добавляться начальные данные. То есть в данном случае данные будут добавляться в таблицу, где хранятся объекты User. Поэтому Entity типизируется типом User.

Далее по цепочке вызывается метод HasData(), который собственно и определяет начальные данные. В данном случае это набор из трех объектов User. При этом для каждого объекта необходимо установить значение первичного ключа - в данном случае значение свойства Id. Причем вне зависимости, генерирует ли база данных для данных автоматически индентификатор или нет, нам в любом случае его надо установить - это основное ограничение при инициализации БД начальными данными.

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

  • При выполнении миграции. (При создании миграции добавляемые данные автоматически включаются в скрипт миграции)

  • При вызове метода Database.EnsureCreated(), который создает БД при ее отсутствии

В случае выше в конструкторе применяется метод Database.EnsureCreated(), поэтому при создании контекста данных

ApplicationContext db = new ApplicationContext();

будет автоматически производиться инициализация бд начальными данными.

Аналогично можно инициализировать данные нескольких сущностей, в том числе связанных между собой:

using Microsoft.EntityFrameworkCore;

public class ApplicationContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;
    public DbSet<Company> Companies { get; set; } = null!;
    public ApplicationContext()
    {
        Database.EnsureDeleted();
        Database.EnsureCreated();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=helloapp1.db");
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // определяем компании
        Company microsoft = new Company { Id = 1, Name = "Microsoft" };
        Company google = new Company { Id = 2, Name = "Google" };
        // определяем пользователей
        User tom = new User { Id = 1, Name = "Tom", Age = 23, CompanyId = microsoft.Id };
        User alice = new User { Id = 2, Name = "Alice", Age = 26, CompanyId = microsoft.Id };
        User sam = new User { Id = 3, Name = "Sam", Age = 28, CompanyId = google.Id };

        // добавляем данные для обеих сущностей
        modelBuilder.Entity<Company>().HasData(microsoft, google);
        modelBuilder.Entity<User>().HasData(tom, alice, sam);
    }
}
public class User
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public int Age { get; set; }
    public Company? Company { get; set; }
    public int? CompanyId { get; set; }
}
public class Company
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public List<User> Users { get; set; } = new();
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850