在.NET Core类库中使用EF Core迁移数据库到SQL Server
前言
如果大家刚使用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.SqlServer Install-Package Microsoft.EntityFrameworkCore.Tools
a)打开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(); m.Property(t => t.UserName)
.IsRequired()
.HasMaxLength(); m.Property(t => t.Password)
.IsRequired()
.HasMaxLength();
});
}
然后同样使用上面的两条命令重新迁移并更新数据库结构
观察数据库表结构已经更新
同理添加字段,删除字段都是一样的迁移操作,还是很方便的
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.Json
b)、属性注解[Column(Order = 1)]对EF Core来说还没有达到可以调整数据库生成字段的顺序,不过我们还是可以修改迁移文件的实体属性的顺序来达到我们想要的效果。下面是我调整之后重新生成的表,是不是看出来和上面的有什么不同,一图胜万语:
c)、最后一步,自己动手试试看:创建一个SeedData迁移文件来添加数据库的初始数据。:)
4、最后
EF Core的强大远不止这些,还有更多的使用方法等着我们去发现,去探索。每天进步一点点,是件很愉快的事情!
在.NET Core类库中使用EF Core迁移数据库到SQL Server的更多相关文章
- 在Asp.Net Core 5 中使用EF Core连接MariaDB
升级到Asp.Net Core 5,使用EF Core连接MariaDB,使用的Nuget包Pomelo.EntityFrameworkCore.MySql也升级到了5.0.0-alpha.2,然后发 ...
- [翻译 EF Core in Action 1.10] 应该在项目中使用EF Core吗?
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- 万字长文,带你彻底理解EF Core5的运行机制,让你成为团队中的EF Core专家
在EF Core 5中,有很多方式可以窥察工作流程中发生的事情,并与该信息进行交互.这些功能点包括日志记录,拦截,事件处理程序和一些超酷的最新出现的调试功能.EF团队甚至从Entity Framewo ...
- .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介
.NET Core 1.0.ASP.NET Core 1.0和EF Core 1.0简介 英文原文:Reintroducing .NET Core 1.0, ASP.NET Core 1.0, and ...
- [翻译 EF Core in Action 1.9] 掀开EF Core的引擎盖看看EF Core内部是如何工作的
Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...
- 【.Net Core 学习系列】-- EF Core实践(DB First)
一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二.准备数据: CREATE DATABASE [Blogging]; GO USE [Blogging ...
- ASP.NET Core MVC+Layui使用EF Core连接MySQL执行简单的CRUD操作
前言: 本章主要通过一个完整的示例讲解ASP.NET Core MVC+EF Core对MySQL数据库进行简单的CRUD操作,希望能够为刚入门.NET Core的小伙伴们提供一个完整的参考实例.关于 ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- ASP.NET Core 开发 - Entity Framework (EF) Core
EF Core 1.0 Database First http://www.cnblogs.com/linezero/p/EFCoreDBFirst.html ASP.NET Core 开发 - En ...
随机推荐
- 阿里云ubuntu安装jdk8+mysql+tomcat
Mysql安装 使用apt-get安装 apt-get install mysql-server apt-get install mysql-client apt-get install libmys ...
- js 获取多少天前
getBeforeDate: function(day, str) { var now = new Date().getTime(); //获取毫秒数 var before = new Date(no ...
- fastDFS文件服务器迁移
在实际的项目应用中,由于服务器替换或项目变更难免会存在fastDFS文件服务器迁移的工作.本文重点介绍fastDFS文件系统在不同情况下的文件迁移处理方案. 1.迁移时IP地址不变 通过文件服务器存储 ...
- 前端开发:H5直播起航
前言 前不久抽空对目前比较火的视频直播,做了下研究与探索,了解其整体实现流程,以及探讨移动端HTML5直播可行性方案. 发现目前 WEB 上主流的视频直播方案有 HLS 和 RTMP,移动 WEB 端 ...
- Leetcode题解(二)
4.Median of Two Sorted Arrays(*) 题目 题目要求找到两个排序数组的中位数. 中位数的定义:当n为奇数时,median = array[n/2];当n为偶数时,media ...
- POJ3468(线段树 区间修改 lazy-tag)
我的线段树真的没救了......还是多练几道吧....... You have N integers, A1, A2, ... , AN. You need to deal with two kind ...
- AngularJS学习篇(十八)
AngularJS API AngularJS 全局 API 用于执行常见任务的 JavaScript 函数集合,如: 比较对象 迭代对象 转换对象 全局 API 函数使用 angular 对象进行访 ...
- Linux特殊字符用法、后台命令管理
!! 重复前一个命令!字符 重复前一个以"字符"开头的命令!num 安装history命令的序号执行命令!?abc 重复之前包含"abc"的命令!-n 重复倒数 ...
- .Net高级进阶,在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码?
本文将通过场景例子演示,来通俗易懂的讲解在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码. 通过一系列优化最终达到两个效果,1.通过代码块来控制事务(分布式事务),2.通过委托优化Tran ...
- 深入分析Android动画(二)
上回书说到Android动画的分类以及基本使用,这会书主要说Android属性动画的原理,对于View动画的原理本篇不做深入分析.对于Android动画的基础请看深入分析Android动画(一) 我们 ...