EFCore+数据库迁移

本随笔只是个人学习笔记记录

说明:本文采用asp.netcore 3.1 空的web项目演示EFCore以及数据库迁移,数据库使用vs2019自带的localdb。

一、EFCore 支持主流关系型数据库

  EFCore 支持主流关系型数据库,包括sqlserver,vs 自带的localdb,oracle,mysql,sqllite,postgresql,db2等。对于不同的关系型数据库,EFCore 都提供了相应

的提供程序(Provider),详情请参考官网: https://docs.microsoft.com/zh-cn/ef/core/providers/?tabs=dotnet-core-cli

 二、数据库上下文DbContext,定义与数据库映射的Entity

  EFCore 通过 DbContext 与数据库建立连接,其对应关系如下图所示:一个DbSet<T> 对应一张表,表的字段,就是类T的属性。

       

  1.使用DbContext 之前,先nuget 添加如下安装包:

  2.定义Entity(与数据库对应的实体)Student 如下:

 public class Student
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime Birthday { get; set; }
        public string Gender { get; set; }
    }

  3.继承DbContext 类如下:

public class MyDataContext:DbContext
    {
        /// <summary>
        /// 配置MyDataContext,配置怎么连接到哪个数据库;使用依赖注入来创建具体的MyDataContext对象。
        /// (在 StartUp类的ConfigureServices中注入。)
        /// </summary>
        /// <param name="options"></param>
        public MyDataContext(DbContextOptions<MyDataContext> options):base(options)
        {

        }
        public DbSet<Student> Students { get; set; }

    }

  

  4.需要将DbContext 注册服务(依赖注入):

public class Startup
    {
        private readonly IConfiguration configuration;

        /// <summary>
        /// 构造函数注入,运行时 会自动注入 _configuration;
        /// </summary>
        /// <param name="_configuration"></param>
        public Startup(IConfiguration _configuration)
        {
            configuration = _configuration;
        }
        public void ConfigureServices(IServiceCollection services)
        {
            var connstr = configuration["ConnStrs:LocalConnStr"];//获取配置文件AppSetting.json中的数据库连接字符串。

           //配置服务,依赖注入
            services.AddDbContext<MyDataContext>( options=> {
                options.UseSqlServer(connstr);
            });

            //注册服务
            services.AddScoped<IRepository<Student>, StudentRepository>();

        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }

  5、存储层使用DbContext 如下:利用DbContext,对数据库的数据进行增删改查。

   接口:

public interface IRepository<T> where T:class
    {
        IEnumerable<T> GetAll();

        IEnumerable<T> GetEntities(Expression<Func<T,bool>> exp);

        T GetById(int Id);

        void Add(T Entity);

        void Modified(T Entity);

        void Delete(T Entity);

    }

  实现类:

public class StudentRepository : IRepository<Student>
    {
        private readonly MyDataContext context;
        public StudentRepository(MyDataContext _context)
        {
            context = _context;//通过构造函数注入,已经在ConfigureServices进行注册了
        }
        public void Add(Student Entity)
        {
            context.Students.Add(Entity);
            context.SaveChanges();
        }

        public void Delete(Student Entity)
        {
            context.Remove(Entity);
        }

        public IEnumerable<Student> GetAll()
        {
            return context.Students.ToList();
        }

        public Student GetById(int Id)
        {
            return context.Students.Find(Id);
        }

        public IEnumerable<Student> GetEntities(Expression<Func<Student,bool>> exp)
        {
            return context.Students.Where(exp);
        }

        public void Modified(Student Entity)
        {
            throw new NotImplementedException();
        }
    }

三、数据迁移:实现Entity与数据库的映射。

  数据迁移,即将程序中DbContext的实体类,映射到数据库中。具体而言就是根据DbContext中的实体类,在数据库中创建表、更改表结构等(即根据Entity,在数据库中设计表)。

迁移主要用到两个命令:Add-Migration xxx  和  Update-Database。可通过 vs自带的 Package Manage Console 工具执行这两个命令完成迁移。

  1.Add-Migration xxx 命令:添加迁移,xxx为描述性单词。如果数据库还没有创建,则会创建一个迁移文件夹 Migrations,迁移文件夹中包含迁移类和快照类。

每次执行迁移文件夹中包含则会生成一个迁移类和一个快照类,每次执行 Add-Migration 都会生成一个迁移类,而快照类只有一个。

迁移类的代码,就是对应创建数据库的代码(或者更新数据库的代码)。

  2.Update-Database 命令:这个命令会使用迁移类的代码,将其转换成sql语句,然后执行到目标数据库。执行成功后,数据库中的表就会和DbContext中的Entity一一对应。如果更新了DbContext中Entity的设计,则再此执行 Add-Migration 和 Update-Database即可,此时会另外生成迁移类,但快照类只有一个。

  3.命令实操:数据库使用VS2019自带的localdb.

         操作时,如果报异常,请参考 https://www.cnblogs.com/liwenqian/p/12746186.html 和 https://www.cnblogs.com/Kit-L/p/12731191.html 处理。

    3.1 配置LocalDB数据库连接:

                打开 vs2019 视图—> SQL Server 对象资源管理器,选则数据库实例,鼠标右键属性获取数据库连接字符串。

    

    将数据库连接字符串,放入配置文件中,并更改连接的数据库名称(后面执行完命令后,数据库会自动创建)

      appsetting.json文件,配置好后,就能通过IConfiguration获取了

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnStrs": {
    "LocalConnStr": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=FyyTestDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
  }
}

    3.2 执行 Add-Migration xxx命令:打开 vs2019->工具->nuget包管理器->程序包管理器控制台 执行命令

    

     执行Add-Migration 命令后,文件生成如下:其中带时间戳的就是迁移文件。

                      

    3.3 执行 Update-Database 命令,根据迁移类的代码,执行到目标数据库。

      

     执行完后,数据库及DbContext中Entity 对应的表就已经创建好了。

    

     其中,EFMigrationsHistory 表记录了每一次迁移。

       

 

原文地址:https://www.cnblogs.com/Fengyinyong/p/13733320.html