在ASP.NET CORE 3.1里使用MySql,ORM框架还是用微软的EF Core,code first,即先写好代码,再按代码(实体模型等)生成数据库,以下为学习笔记:

  1. NuGet安装:Microsoft.EntityFrameworkCore包(3.1.10),然后MySql provider包这里有个坑,就是应使用Pomelo.EntityFrameworkCore.MySql(3.2.4),放弃MySql官方出的:MySql.Data.EntityFrameworkCore,官方的在修改实体模型(比如修改字段长度,改字段名等),使用命令Update-Database时会报错:The method or operation is not implemented,先安装这2个程序包;

  2. 新增实体模型并加一些特性,主要是主键约束、不允许为空、字符串长度、数据库表的字段类型等等;

  public class Person
    { 
        [Required]
        [StringLength(100)]
        public string Name {  get; set; }

        [Required]
        [StringLength(50)]
        public string Email {  get; set; }

        [Required]
        [Range(1, 100)]
        public int Age {  get; set; }

        [Required]
        [StringLength(11, MinimumLength=11)]
        public string Phone {  get; set; }

        [Required]
        [Column(TypeName = "decimal(18,2)")]
        public decimal Salary {  get; set; }
    }
  1. 新建AppDbContext类(自定义名称)并继承自EF Core内置的Dbcontext基类,在构造函数里需传入DbcontextOption<>参数,并传给父类的构造函数;
    public class AppDbContext:DbContext
    { 
        public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
        { 
        }
    }
  1. Startup.cs里注册AppDbContext(上面新增的dbcontext类)服务并初始化(主要是传入数据库链接字符串)等;
        public void ConfigureServices(IServiceCollection services)
        { 
            services.AddControllers();  // webapi服务
            services.AddDbContext<AppDbContext>(options => options.UseMySql(Configuration.GetConnectionString("MySql")));
        }
	// appsettings.json 里的数据库连接字符串
  "ConnectionStrings": { 
    "MySql": "server=localhost; Database=Db; uid=root; pwd=123456;"
  }
  1. 对于需要映射到数据库表的实体,设置为AppDbContex的DbSet<>属性;
    public class AppDbContext:DbContext
    { 
        public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
        { 
        }
        public DbSet<Person> Person {  get; set; }
    }
  1. 创建空的数据库以及表结构;
    1. 方式主要是二种,基于Visual Studio带的包管理器的控制台(PMC)和基于命令行的dotnet ef命令;
    2. 基于Visual Studio带的包管理器的控制台(PMC):如果是Win电脑,则NuGet下载Microsoft.EntityFrameworkCore.Tools(3.1.10),这个包里有迁移命令,注意如果项目有分层,DbContext在一个独立的类库(DAL层或Repository层里)里的话,只需在这个DAL层类库里安装Microsoft.EntityFrameworkCore.Tools程序包,然后点开Package Manager Console(程序包管理控制台),在这里输入相关命令,以下假设项目有DAL层;
  1. 基于命令行的dotnet ef命令:如果不是Win电脑或者想在WIN电脑的CMD下使用数据库创建等相关命令,则需在CMD下执行命令:dotnet tool install –global dotnet-ef,这个工具从EF Core里独立出来了;

  2. 保存项目所有文件并执行生成解决方案(特别是实体模型文件、AppDbContext类等),编译没有问题后,在DAL层下打开PMC(程序包管理控制台)下执行命令:add-migration 自定义个命名(如果在CMD下执行:dotnet ef migrations add 自定义个命名);

  3. 此命令会搜索DBContext类下所有的DBSet以及对应的所有字段,然后和镜像文件比较,如果镜像文件不存在,则生成一个并把所有的表和字段都添加上,如果存在,则比较现有源码里的表结构和镜像文件的表结构的差异,把差异转换成增量文件,并更新镜像文件。这样就生成了迁移文件。注意先执行:生成解决方案,没问题后,再执行:add-migration;

  4. 执行命令后,会在DAL层生成迁移文件目录:Migrations 及相关代码,镜像文件(快照文件)就可以理解是数据库完整表结构的c#实现,有Snapshot字样的文件。而增量文件就是一堆AddColum,DropColumn,CreateTable,RemoveTable等函数,表示这次变化是添加了新字段,删除新字段等等增量操。

  5. 再执行:update-database(这个指令特别切换到CMD下执行,实现的功能与PMC一致),没有PMC的,比如mac电脑可以使用shell命令:dotnet ef database update,就在数据库里生成了空数据库及表结构,数据库中的_EFMigrationHistory表,就是数据库迁移历史表。此命令会连接数据库并查找__EFMigrationHistory表,根据里面的MigrationId,到当前的所有迁移增量文件里找,如果有对应的增量文件,则忽略,把没有在这个表里的所有增量文件执行一遍,通过AddColum,DropColumn,CreateTable,RemoveTable等函数来更新数据库。

  6. 后续修改、新增实体、修改AppDbContext等,重复执行add-migration 、update-database即可更新数据库;

  7. AppDbContext里重写父类的方法:OnModuleCreating(),此方法可以设置实体模型在数据库里生成表时的一些的配置,还可以初始化数据库数据;

		// 填充测试数据
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        { 
            // 填充测试数据,读取json格式的数据源,序列化成实体对象集合
            string basePath = AppContext.BaseDirectory;
            string filePath = Path.Combine(basePath, @"Models\person.json");
            var personStr = File.ReadAllText(filePath);
            var persons= JsonConvert.DeserializeObject<List<person>>(personStr );
            modelBuilder.Entity<TouristRoute>().HasData(persons);
        }

  1. 开发环境下SQL语句打印到控制台,在数据库上下文类(AppDbContext)里
        //SQL语句打印到控制台
        private ILoggerFactory loggerFactory = LoggerFactory.Create(config =>
          { 
              config.AddFilter((category, level) =>
              { 
              //只打印 Information级别的以及数据库命令的
                  return category == DbLoggerCategory.Database.Command.Name &&
                  level == LogLevel.Information;
              }
                  ).AddConsole();
          }
        );
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        { 
            optionsBuilder.UseLoggerFactory(loggerFactory);
        }

EF Core migration分析
基于非源码的EFCore数据库迁移
ASP.NET CORE中使用EF CORE
EFCore + MySql codeFirst 迁移 Migration出现的问题

本文地址:https://blog.csdn.net/zoulei0718/article/details/109527919