浅谈 EF CORE 迁移和实例化的几种方式

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

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

1. Normal & Simple

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

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

  • 安装相关Nuget 包

//Sql Server Database ProviderInstall-Package Microsoft.EntityFrameworkCore.SqlServer//提供熟悉的Add-MigrationUpdate-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 InitializeUpdate-Database
  • 使用方式

using (var context = new MyContext())
{    // TODO}

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

2. 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 实现类的情况下,命令才能成功运行。

3. 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();} }

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

4. 结尾

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

相关文章: 

  • Entity Framework Core 生成跟踪列

  • 在Apworks数据服务中使用基于Entity Framework Core的仓储(Repository)实现

  • Entity Framework Core的贴心:优雅处理带默认值的数据库字段

  • Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

  • Entity Framework Core 软删除与查询过滤器

  • Entity Framework Core 命名约定

  • 全文索引 - Pomelo.EFCore.MySql

  • Entity Framework Core 批处理语句

原文地址:http://www.cnblogs.com/Wddpct/p/7249670.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis 高可用特性之 “持久化” 详解

转载自 Redis 高可用特性之 “持久化” 详解 在之前的文章中&#xff0c;介绍了《Redis的内存模型》&#xff0c;从这篇文章开始&#xff0c;将依次介绍 Redis 高可用相关的知识——持久化、复制(及读写分离)、哨兵、以及集群。 本文将先说明上述几种技术分别解决了 Redis 高…

这本书强烈推荐看看!

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注公众号【雄雄的小课堂】今天&#xff0c;给大家推荐一本书《计算机是怎样跑起来的》&#xff0c;作者&#xff1a;矢泽久雄。也不知道它是怎么进入我的书架的&#xff0c;由于最近一直在看理财类的书籍&#xff0c;所以以前加入…

基于.NET CORE微服务框架 -谈谈Cache中间件和缓存降级

1、前言 surging受到不少.net同学的青睐&#xff0c;也提了不少问题&#xff0c;提的最多的是什么时候集成API 网关&#xff0c;在这里回答大家最近已经开始着手研发&#xff0c;应该在1,2个月内会有个初版API网关&#xff0c;其它像Token身份验证&#xff0c;限流降级等功能完…

1 分钟教会你用 Spring Boot 发邮件

转载自 1 分钟教会你用 Spring Boot 发邮件 Spring Boot 提供了一个发送邮件的简单抽象&#xff0c;使用的是下面这个接口。 org.springframework.mail.javamail.JavaMailSender Spring Boot 提供了一个 starter&#xff0c;并能自动配置&#xff0c;下面来做个小例子&#xf…

小二,先来两桂花豆沙包!

“包子嘞&#xff0c;卖包子嘞&#xff0c;新出锅的大包子&#xff0c;走过路过千万不要错过呦~包子嘞……”某年某月某下午&#xff0c;百万包子铺进来一人&#xff0c;进来便招呼&#xff1a;“小二&#xff0c;包子怎么卖&#xff1f;”小二&#xff1a;“客官&#xff0c;你…

SQL Server 2017 RC1 现已实现 Linux 功能扩展

经过七个预览版本的迭代之后&#xff0c;Microsoft 宣告发布第一个 SQL Server 2017 候选版本。开发人员可以藉由该版本来探索一些扩展 SQL Server Linux 版能力的新改进。 在这些新改进中&#xff0c;首先是对 Linux 上SQL Server 的 Active Directory 身份验证的支持。使用 …

一百馒头一百僧,大僧三个更无争,小僧三人分一个大小和尚得几丁?

如题&#xff1a;一百馒头一百僧&#xff0c;大僧三个更无争&#xff0c;小僧三人分一个大小和尚得几丁&#xff1f; 要求使用java实现求得大僧小僧各有多少人&#xff1f; public class shdjshj {public static void main(String[] args) {for(int i 1;i<100;i){int j 1…

Microsoft使用.NET Core SDK遥测数据

Microsoft发布了采集自.NET Core SDK用户的遥测原始数据集。数据集的时间跨度是从2016年第三季度到2017年第二季度&#xff0c;为了解当前开发人员使用SDK的情况提供了一个视角。据Microsoft的Rich Lander介绍&#xff0c;今后Microsoft将每季度提供一次遥测数据集&#xff0c;…

你们好好的学,回头教教我~

辣椒酱中奖的已经安排发货了&#xff0c;不日即可达到&#xff0c;注意收货。雄雄辣椒酱&#xff0c;免费送~这一周&#xff0c;3班的孩子们都在培训双创的内容&#xff0c;因为这个培训是学校统一组织的&#xff0c;所以对培训的内容以及培训方式我是一无所知的。周二我值班&a…

CAP 介绍及使用【视频】

前言 很多同学可能对于CAP这个项目想有更一步的了解&#xff0c;包括她的工作原理以及适用的场景&#xff0c;所以博主就准备了一场直播给大家讲解了一下&#xff0c;这个视频是直播的一个录像。 由于我这次直播本来是没有打算对外的&#xff0c;所以也是没有怎么准备的&…

投资理财要趁早,基金风险是最小!

大家好&#xff0c;我是雄雄&#xff0c;前几天&#xff0c;有人私信我让我在公众号中推一篇关于理财的文章&#xff0c;说实在的&#xff0c;以我这二把刀的能力&#xff0c;没啥资历教大家理财&#xff0c;不过既然人家都这么说了&#xff0c;那我就来分享一下我自己对于目前…

Java中线程池,你真的会用吗

转载自 Java中线程池&#xff0c;你真的会用吗 在《深入源码分析Java线程池的实现原理》这篇文章中&#xff0c;我们介绍过了Java中线程池的常见用法以及基本原理。 在文中有这样一段描述&#xff1a; 可以通过Executors静态工厂构建线程池&#xff0c;但一般不建议这样使…

解决 CefSharp WPF控件不能使用输入法输入中文的问题(代码已提交到 github)

首先&#xff0c;本文所有 代码已经提交到github&#xff0c;需要的可以直接从github获取&#xff1a;https://github.com/starts2000/CefSharp&#xff0c;希望可以帮助到有需要的朋友们。 CEF 简介 CEF is a BSD-licensed open source project founded by Marshall Greenbl…

java中的泛型类型擦除

大家好&#xff0c;我是雄雄&#xff0c;今天给大家分享的是&#xff1a;java的泛型是类型擦除的。写在前面那么何为类型擦除&#xff1f;类型擦除就是在编译期明确去掉所编程序的类型系统。啥&#xff1f;还不明白&#xff1f;以java泛型为例&#xff0c;java的泛型在编译期有…

性能优化之抛弃Calendar

转载自 性能优化之抛弃Calendar 目前在做限流相关的需求&#xff0c;有这么一个限流策略&#xff0c;和用户相关&#xff0c;当系统发生故障时&#xff0c;允许一个非核心接口按照用户的百分比进行限流&#xff0c;如果完全按照UUID进行hash&#xff0c;那么每次都是限制同一…