在.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(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.Json

b)、属性注解[Column(Order = 1)]对EF Core来说还没有达到可以调整数据库生成字段的顺序,不过我们还是可以修改迁移文件的实体属性的顺序来达到我们想要的效果。下面是我调整之后重新生成的表,是不是看出来和上面的有什么不同,一图胜万语:

c)、最后一步,自己动手试试看:创建一个SeedData迁移文件来添加数据库的初始数据。:)

4、最后

EF Core的强大远不止这些,还有更多的使用方法等着我们去发现,去探索。每天进步一点点,是件很愉快的事情!

(0)

相关推荐

  • 在.NET Core类库中使用EF Core迁移数据库到SQL Server的方法

    前言 如果大家刚使用EntityFramework Core作为ORM框架的话,想必都会遇到数据库迁移的一些问题. 起初我是在ASP.NET Core的Web项目中进行的,但后来发现放在此处并不是很合理,一些关于数据库的迁移,比如新增表,字段,修改字段类型等等,不应该和最上层的Web项目所关联,数据的迁移文件放到这里也感觉有点多余,有点乱乱的感觉,所以才想着单独出来由专门的项目进行管理会比较好,也比较清晰! 注意目标框架选择的是.NET Core 2.0而不是.NET Standard 2.0.

  • .net core实用技巧——将EF Core生成的SQL语句显示在控制台中

    前言 笔者最近在开发和维护一个.NET Core项目,其中使用几个非常有意思的.NET Core相关的扩展,在此总结整理一下. EF Core性能调优 如果你的项目中使用了EF Core, 且正在处于性能调优阶段,那么了解EF Core生成的SQL语句是非常关键的.那么除了使用第三方工具,如何查看EF Core生成的SQL语句呢?这里笔者将给出一个基于.NET Core内置日志组件的实现方式. 创建一个实例项目 我们首先建一个控制台程序,在主程序中我们编写了一个最简单的EF查询. class P

  • 浅谈mybatis中的#和$的区别 以及防止sql注入的方法

    mybatis中的#和$的区别 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id". 2. $将传入的数据直接显示生成在sql中.如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,  如果传入的

  • sqlserver中通过osql/ocmd批处理批量执行sql文件的方法

    利用osql/ocmd批处理批量执行sql文件 注意:在上图中我们可以看到osql 并不支持 SQL Server 2008的所有功能,如果需要使用SQL Server 2008的所有功能可以使用ocmd命令. 有了osql/ocmd命令要批量执行sql文件当然需要写一个批处理命令,例如我们执行上面sql文件就可以在txt中编写下面的语句: 复制代码 代码如下: osql -S"127.0.0.1" -U"sa" -P"sa" -d"N

  • Java实现把excel xls中数据转为可直接插入数据库的sql文件

    我的一贯风格,代码说明一切.. 废话不多说了,直接给大家贴代码了,具体代码如下所示: package Tools; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; im

  • Python的Flask框架中使用Flask-Migrate扩展迁移数据库的教程

    我们在升级系统的时候,经常碰到需要更新服务器端数据结构等操作,之前的方式是通过手工编写alter sql脚本处理,经常会发现遗漏,导致程序发布到服务器上后无法正常使用. 现在我们可以使用Flask-Migrate插件来解决之,Flask-Migrate插件是基于Alembic,Alembic是由大名鼎鼎的SQLAlchemy作者开发数据迁移工具. 具体操作如下: 1. 安装Flask-Migrate插件 $ pip install Flask-Migrate 2. 修改Flask App部分的代

  • .net core项目中常用的几款类库详解(值得收藏)

    前言 至2002微软公司推出.NET平台已近15年,在互联网快速迭代的浪潮中,许多语言已被淘汰,同时也有更多新的语言涌现,但 .Net 依然坚挺的站在系统开发平台的一线阵营中,并且随着.NET Core正式版的到来,迎来新一轮春天. 本文主要给大家介绍了关于.net core项目中常用的几款类库的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 汉字转拼音 1. HxfPinYin 这是我自己根据网上大神提供的源码,再.net core 框架下编译出的类库 主要提供汉字

  • 如何在ASP.NET Core类库项目中读取配置文件详解

    前言 最近有朋友问如何在.net core类库中读取配置文件,当时一下蒙了,这个提的多好,我居然不知道,于是这两天了解了相关内容才有此篇文章的出现,正常来讲我们在应用程序目录下有个appsettings.json文件对于相关配置都会放在这个json文件中,但是要是我建立一个类库项目,对于一些配置比如密钥或者其他需要硬编码的数据放在JSON文件中,在.net core之前配置文件为web.config并且有相关的类来读取节点上的数据,现如今在.net core中为json文件,那么我们该如何做?本

  • ASP.NET 5已终结,迎来ASP.NET Core 1.0和.NET Core 1.0

    ASP.NET 在过去的 15 年里是个非常不错的"品牌". ASP.NET 4.6 已经支持在生产环境使用:http://get.asp.net. 但是,命名是新的,完全截取自 ASP.NET 框架 -- "ASP.NET 5",但这并不是个好主意,其中一个原因是:5 > 4.6,这样看起来 ASP.NET 5 比 ASP.NET 4.6 版本号更大,更好,甚至是可以替代 ASP.NET 4.6. 所以修改了名字,选择了一个更好的版本号. 重新引入 ASP.

  • SQL Server 2008中的数据表压缩功能详细介绍

    SQL Server 2005 SP2为我们带来了vardecimal功能,当时针对decimail和numeric数据类型推出了新的存储格式--vardecimal.vardecimal存储格式允许 decimal和numeric数据类型的存储作为一个可变长度列. 这项功能使得原来定长的decimal数据在数据文件中以可变长的格式存储,据称这项功能可以为典型的数据仓库节省30%的空间,而SQL Server 2008在这一基础上又进一步增强了数据压缩功能.SQL Server 2008现在支持

随机推荐