时间:2021-05-26
前言
如果大家刚使用EntityFramework Core作为ORM框架的话,想必都会遇到数据库迁移的一些问题。
起初我是在ASP.NET Core的Web项目中进行的,但后来发现放在此处并不是很合理,一些关于数据库的迁移,比如新增表,字段,修改字段类型等等,不应该和最上层的Web项目所关联,数据的迁移文件放到这里也感觉有点多余,有点乱乱的感觉,所以才想着单独出来由专门的项目进行管理会比较好,也比较清晰!
注意目标框架选择的是.NET Core 2.0而不是.NET Standard 2.0。
0、前期准备
a)、表实体定义,这个是在.NET Standard 2.0的类库中存放的。
/// <summary> /// 系统应用的用户实体 /// </summary> public class ApplicationUser : BaseModel { /// <summary> /// 用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } /// <summary> /// 邮件地址 /// </summary> public string Email { get; set; } }b)、新建一个.NET Core 2.0的类库,并定义好我们所要使用的数据库上下文,很简单,接下来开始我们的正文
/// <summary> /// 系统上下文 /// </summary> public class LightContext : DbContext { public LightContext(DbContextOptions<LightContext> options) : base(options) { } /// <summary> /// 系统应用用户 /// </summary> public DbSet<ApplicationUser> ApplicationUser { get; set; } /// <summary> /// 角色表 /// </summary> public DbSet<Role> Role { get; set; } }1、问题汇总
首先要确保仓储类库中已经引入以下两个Nuget包,没有的话请使用包管理器进行安装。不建议直接引入原包:Microsoft.AspNetCore.All,按需引入即可
Install-Package Microsoft.EntityFrameworkCore.SqlServerInstall-Package Microsoft.EntityFrameworkCore.Toolsa)打开CMD,然后切换到类库所在路径下,执行以下命令。不过你也可以使用程序包管理器控制台(PMC)进行迁移,但是会有少许变化,部分命令见下表:
迁移命令描述 CMD命令 PMC命令 创建迁移:migrationname为迁移名称 dotnet ef migrations add migrationname add-migration migrationname 移除迁移(删除最近的一次迁移) dotnet ef migrations remove remove-migration 应用最新的迁移(使迁移文件应用到数据库) dotnet ef database update update-database 应用指定的迁移 dotnet ef database update migrationname update-database migrationname 查看迁移列表 dotnet ef migrations list 查看数据库上下文信息 dotnet ef dbcontext info
dotnet ef错误提示:
未找到与命令“dotnet-ef”匹配的可执行文件
解决方法:
在项目文件Light.Repository.csproj中添加以下节点
<ItemGroup> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.1" /></ItemGroup>重新执行上面的命令,如果出现了EF Core的标志(一头蓄势待发的野马)表示已经成功
b)、执行以下命令进行迁移
dotnet ef migrations add InitLightDB错误提示:
The specified framework version '2.0' could not be parsed
The specified framework 'Microsoft.NETCore.App', version '2.0' was not found.
- Check application dependencies and target a framework version installed at:
\
- Alternatively, install the framework version '2.0'.
解决方法:
在项目文件中添加以下节点:
<PropertyGroup> <TargetFramework>netcoreapp2.0</TargetFramework> <RuntimeFrameworkVersion>2.0.3</RuntimeFrameworkVersion> </PropertyGroup>c)、重新执行b步骤的命令,报错信息如下:
错误提示:
Unable to create an object of type 'LightContext'. Add an implementation of 'IDesignTimeDbContextFactory<LightContext>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
这个问题如果是在Web项目,并且配置了DbContext的链接字符串的话,是不会出现此问题的。很显然是迁移命令没有找到DbConnectionString导致的,接下来我们按照提示,实现一个IDesignTimeDbContextFactory<LightContext>试试
解决方法:
创建一个与DbContext同一目录下的DesignTimeDbContextFactory文件,然后实现接口中的方法CreateDbContext,并配置ConnectionString
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<LightContext> { public LightContext CreateDbContext(string[] args) { var builder = new DbContextOptionsBuilder<LightContext>(); builder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;Initial Catalog=Light;"); return new LightContext(builder.Options); } }再次执行迁移命令,终于成功了。
成功提示:
Done. To undo this action, use 'ef migrations remove'
同时类库下面会生成Migrations文件夹以及相关的迁移文件
2、小试迁移命令
a)、使用以下命令应用迁移,生成数据库和表
dotnet ef database update通过VS的SQL Server资源管理器查看生成数据库的结构,其中__EFMigrationsHistory为每次迁移的记录表
b)、因为string类型的字段迁移到数据库之后的数据类型为nvarchar(max)并且是可空类型的,下面我们就使用Fluent API对ApplicationUser表字段进行配置,同样你也可以使用属性注解的方式进行配置,因为我自己不喜欢“污染”表实体
public static void ConfigApplicationUser(ModelBuilder modelBuilder) { modelBuilder.Entity<ApplicationUser>(m => { m.Property(t => t.Email) .HasMaxLength(50); m.Property(t => t.UserName) .IsRequired() .HasMaxLength(50); m.Property(t => t.Password) .IsRequired() .HasMaxLength(20); }); }然后同样使用上面的两条命令重新迁移并更新数据库结构
观察数据库表结构已经更新
同理添加字段,删除字段都是一样的迁移操作,还是很方便的
3、扩展
a)、为了方便演示,其实上面在类库中执行迁移时的数据库连接字符串是写死的,那么最好的办法是应该去读取Web项目下已经配置好的连接,这样就能保证上下的一致性,不用再去为了EF的迁移而单独维护一个多余的数据库连接配置。改造也很简单,即通过Configuration组件读取appsettings.json的ConnectionStrings节点,改造之后是这样子的:
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<LightContext> { public LightContext CreateDbContext(string[] args) { Directory.SetCurrentDirectory("..");//设置当前路径为当前解决方案的路径 string appSettingBasePath = Directory.GetCurrentDirectory() + "/Light.AuthorityApi";//改成你的appsettings.json所在的项目名称 var configBuilder = new ConfigurationBuilder() .SetBasePath(appSettingBasePath) .AddJsonFile("appsettings.json") .Build(); var builder = new DbContextOptionsBuilder<LightContext>(); //builder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;Initial Catalog=Light;"); builder.UseSqlServer(configBuilder.GetConnectionString("LightConnection")); return new LightContext(builder.Options); } }注意需要额外引入下面这个Nuget包:
Install-Package Microsoft.Extensions.Configuration.Jsonb)、属性注解[Column(Order = 1)]对EF Core来说还没有达到可以调整数据库生成字段的顺序,不过我们还是可以修改迁移文件的实体属性的顺序来达到我们想要的效果。下面是我调整之后重新生成的表,是不是看出来和上面的有什么不同,一图胜万语:
c)、最后一步,自己动手试试看:创建一个SeedData迁移文件来添加数据库的初始数据。:)
4、最后
EF Core的强大远不止这些,还有更多的使用方法等着我们去发现,去探索。每天进步一点点,是件很愉快的事情!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
python3manage.pymakemigrations#生成数据库迁移文件python3manage.pymigrate#迁移数据库简简单单两条命令就完成
在使用Django2.0并配置了mysql作为数据库时,启动报错:报错1:找不到mysqlclientdjango.core.exceptions.Improp
一、问题由来现在进行项目改造,数据库需要迁移,由原来的使用gbase数据库改为使用oracle数据库,今天测试人员在测试时后台报了一个异常。把sql语句单独复制
如何在Excel中使用SQL语言实现数据查询?SQL语句是一种标准的数据库语言,其可以在任何关系型数据库管理系统中使用。本文介绍使用SQL语句实现对Excel工
说明:MariaDB是基于MySQL的开源数据库,兼容MySQL,现有的MySQL数据库可以迁移到MariaDB中使用MariaDB下载:32位:http://