【EFCore】配置迁移Migration

文章介绍了EFCore中如何使用CodeFirst进行数据库迁移,包括创建迁移、移除迁移和更新数据库的命令。通过示例展示了如何修改模型并自动更新数据库结构,同时配置一对一、一对多和多对多的关系。此外,还提到了日志输出到控制台的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在EF中,有几种开发方式DBFristCodeFirstModelFirstCodeFirsrtFromDB

但在EFCore中,一般用CodeFirst

EF中当我们要修改数据表结构时,我们要自己去数据库更改表结构,而如果生成sql的语句是直接删除全部表,再生成全部表,这必定会造成数据的丢失

所以才会有EFCore的迁移功能的诞生

EFCore的迁移功能可以自动生成升级脚本,只要修改模型,再创建迁移更新数据库即可

安装几个包

Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Migrations

命令

创建迁移 add-migration migrationname

移除迁移 remove-migration

应用最新的迁移 update-database

应用指定的迁移 update-database migrationname
在这里插入图片描述

模型

先创建用户模型

public class UserInfo
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

创建上下文

public class EFCoreMigrationContext : DbContext
{
    private string ConnectionString = "Server=GREAMBWANG-DC\\MSSQLSERVER2019;Database=EFCoreMigrationTest;Trusted_Connection=True;";
 
    public DbSet<UserInfo> UserInfo { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(ConnectionString);
    }
}

在工具–NuGet包管理器–打开程序包管理控制台
在这里插入图片描述

执行 add-migration Init01命令

项目自动生成迁移文件
在这里插入图片描述
执行update-database命令

生成数据库
在这里插入图片描述
在模型字段发生变化时,使用add-migration migrationname添加迁移记录

再使用update-database 更新数据库

现在如果更改UserInfo的字段Name改为Name2,生成迁移文件

再将Name2改为Name,再创建模型中也可以添加初始化数据

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

对比3个迁移文件,发现迁移文件都是依赖上一个迁移文件的
在这里插入图片描述

表之间的对应关系

一般的关系有一对一,一对多,多对多

OnModelCreating中创建表关系

各个模型

public class UserInfo
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public virtual UserInfoExt UserInfoExt { get; set; }
    public virtual List<OrderInfo> OrderInfo { get; set; }
    public virtual List<UserRoleMapping> UserRoleMapping { get; set; }
}
public class UserInfoExt
{
    [Key]
    public int Id { get; set; }
    public int UserInfoId { get; set; }
    public string Sign { get; set; }
    public virtual UserInfo UserInfo { get; set; }
}
public class OrderInfo
{
    [Key]
    public int Id { get; set; }
    public int UserInfoId { get; set; }
    public string Content { get; set; }
    public virtual UserInfo UserInfo { get; set; }
}
public class RoleInfo
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<UserRoleMapping> UserRoleMapping { get; set; }
}
public class UserRoleMapping
{
    public int UserInfoId { get; set; }
    public int RoleInfoId { get; set; }
    public UserInfo UserInfo { get; set; }
    public RoleInfo RoleInfo { get; set; }
}

其中

用户信息表与用户额外信息表是一对一的关系

用户信息表与订单信息表是一对多的关系

用户信息表与角色信息表是多对多的关系

我们可以配置日志输出到控制台,查看执行的sql

安装两个包

Microsoft.Extensions.Logging

Microsoft.Extensions.Logging.Console
public class EFCoreMigrationContext : DbContext
{
    public static readonly ILoggerFactory MyLoggerFactory
        = LoggerFactory.Create(builder => builder.AddConsole());
 
    private string ConnectionString = "Server=GREAMBWANG-DC\\MSSQLSERVER2019;Database=EFCoreMigrationTest;Trusted_Connection=True;";
 
    public DbSet<UserInfo> UserInfo { get; set; }
 
    public DbSet<UserInfoExt> UserInfoExt { get; set; }
 
    public DbSet<OrderInfo> OrderInfo { get; set; }
    public DbSet<RoleInfo> RoleInfo { get; set; }
    public DbSet<UserRoleMapping> UserRoleMapping { get; set; }
 
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(ConnectionString).UseLoggerFactory(MyLoggerFactory);
    }
 
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //创建数据
        modelBuilder.Entity<UserInfo>().HasData(new UserInfo()
        {
            Id = 1,
            Name = "haha",
            Age = 18
        });
 
        //一对一
        modelBuilder.Entity<UserInfoExt>().HasOne(u => u.UserInfo).WithOne(u=>u.UserInfoExt).HasForeignKey<UserInfoExt>(e => e.UserInfoId);
 
        //一对多
        modelBuilder.Entity<UserInfo>().HasMany(u => u.OrderInfo).WithOne(o => o.UserInfo).HasForeignKey(o => o.UserInfoId);
 
        //多对多
        modelBuilder.Entity<UserRoleMapping>().HasOne(u => u.UserInfo).WithMany(u => u.UserRoleMapping).HasForeignKey(u => u.UserInfoId);
        modelBuilder.Entity<UserRoleMapping>().HasOne(u => u.RoleInfo).WithMany(u => u.UserRoleMapping).HasForeignKey(u => u.RoleInfoId);
        //也可以这样
        modelBuilder.Entity<UserRoleMapping>().HasKey(p => new { p.UserInfoId, p.RoleInfoId });
    }
}

添加数据

EFCoreMigrationContext context = new EFCoreMigrationContext();
 
UserInfo userInfo = new UserInfo() { Name = "aa", Age = 18 };
 
userInfo.UserInfoExt = new UserInfoExt() { Sign = "aaa" };
 
userInfo.OrderInfo = new List<OrderInfo>()
{
    new OrderInfo(){ Content ="订单1"},
    new OrderInfo(){ Content="订单2"}
};
 
context.UserInfo.Add(userInfo);
 
context.SaveChanges();
 
var user = context.UserInfo.FirstOrDefault();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值