本文作者:小黑黑

[EFCore]数据库初始化

小黑黑 11个月前 ( 05-20 ) 838 抢沙发
[EFCore]数据库初始化摘要:      数据库初始化用于一组初始的数据填充到数据库的过程,如:当我们初始化数据库的时候,希望为数据库的某些表填充一些初始值(管理员的信息,...

     数据库初始化用于一组初始的数据填充到数据库的过程,如:当我们初始化数据库的时候,希望为数据库的某些表填充一些初始值(管理员的信息,角色和权限等)。EF Core为我们提供了3中方式去完成数据库初始化:

        1、OnModelCreating中配置

        2、手动迁移自定义项

        3、自定义初始化逻辑


一、OnModelCreating中配置

首先我们创建一张Blog表和Post表,使用这两张表演示如何在OnModelCreating中初始化数据

/// <summary>
/// 博客表
/// </summary>
public class Blog
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Url地址
    /// </summary>
    public string Url { get; set; }
}

/// <summary>
/// 文章表
/// </summary>
public class Post
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 标题
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 内容
    /// </summary>
    public string Content { get; set; }

    /// <summary>
    /// BlogId
    /// </summary>
    public int BlogId { get; set; }

    public virtual Blog Blog { get; set; }
}


/// <summary>
/// 数据库上下文
/// </summary>
public class BloggingDbContext : DbContext
{

    public BloggingDbContext(DbContextOptions<BloggingDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //配置Blog表和Post表的关系
        modelBuilder.Entity<Blog>().HasMany(t => t.Posts).WithOne(t => t.Blog).HasForeignKey(k => k.BlogId);

        //初始化Blog表数据
        modelBuilder.Entity<Blog>().HasData(
            new Blog()
            {
                Id = 1,
                Url = "https://www.aspnetcore.vip"
            }
        );

        //初始化Post表数据
        modelBuilder.Entity<Post>().HasData(
            new Post()
            {
                Id = 1,
                BlogId = 1,
                Title = "测试文章标题",
                Content = "测试文章内容"
            });
        }

    public DbSet<Blog> Blog { get; set; }
}

我们使用EF迁移命令,查看数据库,我们可以看到Blog和Post表已经添加了一条初始化数据

Add-Migration InitCreate
Update-Database

二、手动迁移自定义项

首先我们创建两张表:User和UserInfo,并在OnModelCreating中创建这两张表的一对一关系

/// <summary>
/// 用户表
/// </summary>
public class User
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 姓
    /// </summary>
    public string FirstName { get; set; }

    /// <summary>
    /// 名
    /// </summary>
    public string LastName { get; set; }
}

/// <summary>
/// 用户详情表
/// </summary>
public class UserInfo
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 身份证号
    /// </summary>
    public string IdCard { get; set; }

    public int UserId { get; set; }

    public virtual User User { get; set; }
}

/// <summary>
/// 数据库上下文
/// </summary>
public class BloggingDbContext : DbContext
{

    public BloggingDbContext(DbContextOptions<BloggingDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        
        //配置User表和UserInfo表一对一关系
        modelBuilder.Entity<UserInfo>().HasOne(t => t.User).WithOne().HasForeignKey<UserInfo>(k => k.UserId);
    }

    public DbSet<User> User { get; set; }
}

接着我们使用Add-Migration InitDatabase命令进行数据迁移,使用命令后,我们会生成 时间_InitDatabase.cs文件,我们在此文件中配置数据初始化信息,在Up方法的中,我们添加初始化数据。

public partial class InitDatabase : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        #region 使用Add-Migration命令会自动生成以下信息

        migrationBuilder.CreateTable(
            name: "User",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                FirstName = table.Column<string>(nullable: true),
                LastName = table.Column<string>(nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_User", x => x.Id);
            });

        migrationBuilder.CreateTable(
            name: "UserInfo",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                IdCard = table.Column<string>(nullable: true),
                UserId = table.Column<int>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_UserInfo", x => x.Id);
                table.ForeignKey(
                    name: "FK_UserInfo_User_UserId",
                    column: x => x.UserId,
                    principalTable: "User",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

        migrationBuilder.CreateIndex(
            name: "IX_UserInfo_UserId",
            table: "UserInfo",
            column: "UserId",
            unique: true);

        #endregion

        #region 添加初始化数据

        //添加User数据
        migrationBuilder.InsertData(
            table: "User",
            columns: new[] { "Id", "FirstName", "LastName" },
            values: new object[] { 1, "张", "三" });

        //添加UserInfo数据
        migrationBuilder.InsertData(
            table: "UserInfo",
            columns: new[] { "Id", "UserId", "IdCard" },
            values: new object[] { 1, 1, "123456789012345678" });

        #endregion
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "UserInfo");

        migrationBuilder.DropTable(
            name: "User");
    }
}

接着我们使用Update-Database命令更新数据库,查看数据库,User表和UserInfo表中已经添加了初始化数据。

三、自定义初始化逻辑

首先我们创建一个SeedData类,此类作为我们数据库初始化的配置类,提供一个数据库初始化的方法Initialize方法,在里面我们为需要初始化的表进行初始化信息。

/// <summary>
/// 数据库初始化类
/// </summary>
public class SeedData
{
    private readonly BloggingDbContext _dbContext;

    public SeedData(BloggingDbContext dbContext)
    {
        this._dbContext = dbContext;
    }

    /// <summary>
    /// 初始化数据
    /// </summary>
    public void Initialize()
    {
        //如果数据库不存在,则创建数据库
        _dbContext.Database.EnsureCreated();

        //添加用户表信息
        User user = new User()
        {
            FirstName = "张",
            LastName = "三"
        };

        _dbContext.User.Add(user);

        //添加用户信息详情表信息
        UserInfo userInfo = new UserInfo()
        {
            UserId = 1,
            IdCard = "123456789012345678"
        };

        _dbContext.Set<UserInfo>().Add(userInfo);

        _dbContext.SaveChanges();
    }
}

/// <summary>
/// 数据库上下文
/// </summary>
public class BloggingDbContext : DbContext
{

    public BloggingDbContext(DbContextOptions<BloggingDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        
        //配置User表和UserInfo表一对一关系
        modelBuilder.Entity<UserInfo>().HasOne(t => t.User).WithOne().HasForeignKey<UserInfo>(k => k.UserId);
    }

    public DbSet<User> User { get; set; }
}

//控制台程序启动类
class Program
{
    static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();

        var configurationBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json");
        var configuration = configurationBuilder.Build();

        serviceCollection.AddDbContext<BloggingDbContext>(options => options.UseSqlServer(configuration.GetConnectionString("Blogging")));

        var service = serviceCollection.BuildServiceProvider();

        //创建SeedData类
        var instance = ActivatorUtilities.CreateInstance<SeedData>(service);
        //调用Initialize方法初始化数据
        instance.Initialize();

        Console.Read();
    }
}


分享到: 网站分享代码

发表评论

快捷回复:

评论列表 (暂无评论,838人围观)参与讨论

还没有评论,来说两句吧...