出于学习和测试的简单需要,使用 Console 来作为 EF CORE 的承载程序是最合适不过的。今天笔者就将平时的几种使用方式总结成文,以供参考,同时也是给本人一个温故知新的机会。因为没有一个完整的脉络,所以也只是想起什么写点什么,不通顺的地方还请多多谅解。

本文对象数据库默认为 VS 自带的 LocalDB

  1. Normal & Simple

先介绍一种最简单的构建方式,人人都会。

  • 新建 Console 应用程序,命名自定

  • 安装相关Nuget 包

//Sql Server Database Provider
Install-Package Microsoft.EntityFrameworkCore.SqlServer //提供熟悉的Add-Migration,Update-Database等Powershell命令,不区分关系型数据库类型
Install-Package Microsoft.EntityFrameworkCore.Tools
  • 自定义 DbContext
public class MyContext:DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=ConsoleApp;Trusted_Connection=True;MultipleActiveResultSets=true;");
}
}
  • 执行迁移和更新命令
Add-Migration Initialize
Update-Database
  • 使用方式
using (var context = new MyContext())
{
// TODO
}

刚以上,我们便见识到了了一种最平常也是最简单的使用方式,接下来,让我们用其他方式去慢慢地改造它,从而尽可能地接触更多的用法。

  1. Level Up

2.1 准备工作

将第一步生成的数据库,迁移文件和使用方式内容全部删除。

2.2 更新 MyContext 内容

删除 MyContext 中的 OnConfiguring 方法及其内容,增加含有 DbContextOptions 类型参数的构造器,我们的MyContext看起来应该是下面这个样子。

public class MyContext : DbContext
{
public MyContext(DbContextOptions options) : base(options)
{
}
}

假如我们此时仍然再执行迁移命令,VS将提示以下错误

No parameterless constructor was found on 'MyContext'. Either add a parameterless constructor to 'MyContext' or add an implementation of 'IDbContextFactory' in the same assembly as 'MyContext'.

添加无参构造器的方式之后再讲解,先来按照提示信息添加一个 IDbContextFactory 的实现类。

public class MyContextFactory : IDbContextFactory<MyContext>
{
public MyContext Create(DbContextFactoryOptions options)
{
var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=ConsoleApp;Trusted_Connection=True;MultipleActiveResultSets=true;"); return new MyContext(optionsBuilder.Options);
}
}

之后再次运行迁移和更新数据库的命令也是水到渠成。

2.3 使用方式:构造器实例化

既然 MyContext 含有 DbContextOptions 类型参数的构造器,那就手动创建一个参数实例注入即可。

var contextOptionsBuilder = new DbContextOptionsBuilder<MyContext>();
contextOptionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=ConsoleApp;Trusted_Connection=True;MultipleActiveResultSets=true;"); // 注入配置选项
using (var context = new MyContext(contextOptionsBuilder.Options))
{
// TODO
}

经此,我们知道了迁移命令会检测 Context 的相关配置入口,只有在满足存在 OnConfiguring 方法或者存在自建 IDbContextFactory 实现类的情况下,命令才能成功运行。

  1. Day Day Up

目前为止,我们已经知道如何手动迁移和实例化 Context 的步骤了所以让我们更进一步。写过 ASP.NET CORE 的人可能知道在 ASP.NET CORE 中,Context 常常以依赖注入的方式引入到我们的 Web 层,Service 层,或者 XXCore 层中(话说笔者最近最喜欢的解决方案开发架构就是伪 DDD 的四层架构,有空再介绍吧)。其实在 Console 应用中,这也可以很容易实现,具体的依赖注入引入可以参考笔者的上一篇博客,所以最终的代码效果如下:

var serviceCollection = new ServiceCollection();
serviceCollection.AddDbContext<MyContext>(c =>
{
c.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=ConsoleApp;Trusted_Connection=True;MultipleActiveResultSets=true;");
}); var serviceProvider = serviceCollection.BuildServiceProvider(); using (var context = serviceProvider.GetService<MyContext>())
{
//context.Database.Migrate();
}

至此,我们便基本完成了本文的主题,唯一有些美中不足的是我们的数据库连接字符串好像到处都是,这不是什么大问题,笔者直接将 Configuration 的配置代码贴在下面,这也是 ABP 中的方式。

public class AppConfigurations
{
private static readonly ConcurrentDictionary<string, IConfigurationRoot> ConfigurationCache; static AppConfigurations()
{
ConfigurationCache = new ConcurrentDictionary<string, IConfigurationRoot>();
} public static IConfigurationRoot Get(string environmentName = null)
{
var cacheKey = "#" + environmentName;
return ConfigurationCache.GetOrAdd(
cacheKey,
_ => BuildConfiguration(environmentName)
);
} private static IConfigurationRoot BuildConfiguration(string environmentName = null)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true, true); if (!string.IsNullOrWhiteSpace(environmentName))
builder = builder.AddJsonFile($"appsettings.{environmentName}.json", true); builder = builder.AddEnvironmentVariables(); return builder.Build();
}
}

这个工具类的使用方式就不再赘述了。

  1. 结尾

最后,想必会有人问为什么要折腾这样一个小小的 Console 应用呢?其实通过这样一步步下来,我们可以发现一些项目功能上的亮点,比如既然可以自配置 DbContext 的 Option 选项,同时我们也知道了如何在类库和 Console 项目中添加依赖注入以及 Configuration 提取链接参数的功能,那针对三层架构或是 DDD 项目增加含真实数据库或是内存数据库(InMemory)的单元测试,或者是自动Migrate Context 和更新数据库也将是十分简单的一件事,至少看起来会比官方的示例更加真实和具有可操作性。而这部分内容笔者也将会在之后的博文中给出。

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan

浅谈 EF CORE 迁移和实例化的几种方式的更多相关文章

  1. 【ASP.NET MVC系列】浅谈ASP.NET 页面之间传值的几种方式

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  2. [OpenSource]浅谈.Net和Java互相调用的三种方式

    在很多的大型系统开发中,开发工具往往不限制于同一种开发语言,而是会使用多种开发语言的混合型开发.目前Java和.Net都声称自己占85%的市场份额,不管谁对谁错,Java和.Net是目前应用开发的两个 ...

  3. 浅谈.Net和Java互相调用的三种方式

    在很多的大型系统开发中,开发工具往往不限制于同一种开发语言,而是会使用多种开发语言的混合型开发.目前Java和.Net都声称自己占85%的市场份 额,不管谁对谁错,Java和.Net是目前应用开发的两 ...

  4. Cookies 初识 Dotnetspider EF 6.x、EF Core实现dynamic动态查询和EF Core注入多个上下文实例池你知道有什么问题? EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)

    Cookies   1.创建HttpCookies Cookie=new HttpCookies("CookieName");2.添加内容Cookie.Values.Add(&qu ...

  5. Spring中bean实例化的三种方式

    之前我已经有好几篇博客介绍Spring框架了,不过当时我们都是使用注解来完成注入的,具体小伙伴可以参考这几篇博客(Spring&SpringMVC框架案例).那么今天我想来说说如何通过xml配 ...

  6. Spring bean管理器 bean实例化的三种方式

    bean实例化的三种方式实现 第一种:使用类的无参数构造方法创建(常用 重要) 第一种实例化方式最常用,实例化类时会通过调用无参构造方法创建.示例代码如下: package spring.com.Us ...

  7. 【Spring】的【bean】管理(XML配置文件)【Bean实例化的三种方式】

    Bean实例化的三种方式 说明:通过配置文件创建对象就称为Bean实例化. 第一种:使用类的无参构造创建(重点) 实体类 package com.tyzr.ioc; public class User ...

  8. 再谈EF Core内存数据库单元测试问题

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:在用EF Core的内存数据库进行单元测试的时候遇到"无法访问已释放的对象& ...

  9. 浅谈.Net Core中使用Autofac替换自带的DI容器

    为什么叫 浅谈 呢?就是字面上的意思,讲得比较浅,又不是不能用(这样是不对的)!!! Aufofac大家都不陌生了,说是.Net生态下最优秀的IOC框架那是一点都过分.用的人多了,使用教程也十分丰富, ...

随机推荐

  1. KNN算法介绍

    KNN算法全名为k-Nearest Neighbor,就是K最近邻的意思. 算法描述 KNN是一种分类算法,其基本思想是采用测量不同特征值之间的距离方法进行分类. 算法过程如下: 1.准备样本数据集( ...

  2. JS阻塞以及CSS阻塞

    一.JS阻塞 所有的浏览器在下载JS文件的时候,会阻塞页面上的其他活动,包括其他资源的下载以及页面内容的呈现等等,只有当JS下载.解析.执行完,才会进行后面的 操作.在现代的浏览器中CSS资源和图片i ...

  3. [1] Entity Framework / Code First

    CodeFirst是EntityFramework的一种技术手段,因为传统编程方式都是先建立数据库,然后根据数据库模型为应用程序建模,再进行开发:CodeFirst从字面上理解就是代码先行,先在程序中 ...

  4. Log4PHP 配置和使用

    Log4PHP2.3.0使用解释 1. 什么是Log4PHP Log4php它为apche组织维护项目,是Log4xx系列日志组件之一,log4j在JAVA中可算是大名鼎鼎的日志开发包.Log4PHP ...

  5. tomcat抬头有“选择”或“选定”,导致tomcat无法运行问题

    2. 遇到tomcat抬头有"选择"或"选定",导致tomcat无法运行问题 解决:在tomcat抬头右键--属性,去掉"快速编辑模式"勾选 ...

  6. 关于MATLAB处理大数据坐标文件2017622

    今天新提交了一次数据,总量达到10337个,本以为成绩会突飞猛进,没想到还是不如从前 但是已经找到人工鼠标轨迹的程序,有待完善,接下来兵分四路:找特征.决策树.完善人工轨迹程序,使其可以将生成的数据自 ...

  7. 一起学习c++11——c++11中的新增的容器

    c++11新增的容器1:array array最早是在boost中出现:http://www.boost.org/doc/libs/1_61_0/doc/html/array.html 当时的初衷是希 ...

  8. Redux-Saga学习心得

    # Redux Saga ## 简述- Reducers负责处理action的state更新:- Sagas负责协调那些复杂或异步的操作. ## 安装 npm install --save redux ...

  9. 12.引入依赖项目的时候,如果找不到jar

    原因是bin没有生成,先clean依赖包,再clean原工程包,就可以了

  10. keyStore很重要,千万不能丢失

    打包apk的时候需要对apk文件进行签名,如果想要自己给apk签名那么就要自己创建keystore.1.签名的意义为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package N ...