在上一篇文章中(Asp.Net Core 轻松学-10分钟使用EFCore链接MSSQL数据库)[http://www.javashuo.com/article/p-quroiyoe-n.html],介绍了 EFCore 链接 MSSQL 的使用方法,在本章中,将继续介绍如何利用 EFCore 链接到 MariaDB/MySql 和 PostgreSQL 数据库,同时,在一个项目中,如何添加多个数据库上下文对象,并在业务中使用多个上下文对象,经过这两章的学习,你将掌握使用 EFCore 链接 MSSQL/MariaDB/MySql/PostgreSQL 的能力。在 .NETCore 的时代,因为其设计的独特性(区别于.NetFramework),使得咱们很是容易的使用各类开源的、跨平台的产品和中间件,做为普通程序员,经过普遍参与和使用开源产品,是咱们责无旁贷的责任和义务,这种行为将进一步的扩大 .Net Core 的生态圈,进而影响整个开发行业。闲话说完,进入今天的正题,链接第三方数据库和支持多个上下文对象。html
MariaDB基于MySQL并遵循GPL v2受权使用的。 她是由以Monty Program Ab为主要管理者的MariaDB社区开发的。MariaDB与另外一分支MySQL最新版保持同步更新。在MariaDB工做与在MySQL下工做几乎如出一辙,她们有相同的命令、界面,以及在MySQL中的库与API,因此MariaDB能够说是为替换MySQL量身定作的,因此它们之间是相通用(兼容),换用后连数据库都没必要转换并能够得到MariaDB提供的许多更好的新特性。
以上介绍来自官方文档 https://mariadb.com/kb/zh-cn/mariadb-mariadb/mysql
首先建立一个 Asp.Net Core WebApi 2.2 的项目 Ron.OtherDB,并从 NuGet 仓库引用包 Pomelo.EntityFrameworkCore.MySql,我本地安装的数据库是 MariaDB,从介绍中得知,MariaDB 和 MySql 的使用方式几乎是彻底一致的,因此这里使用 Pomelo.EntityFrameworkCore.MySql 链接 MariaDB 也是没有任何问题的git
下面将编写两个业务实体 Topic/Post,在本章中,不管是链接 MariaDB/MySql 仍是 PostgreSQL,都将使用这两个实体对象程序员
public class Topic { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public DateTime CreateTime { get; set; } public ICollection<Post> Posts { get; set; } } public class Post { public int Id { get; set; } public int TopicId { get; set; } public string Content { get; set; } public DateTime CreateTime { get; set; } public Topic Topic { get; set; } }
public class MySqlForumContext : DbContext { public MySqlForumContext(DbContextOptions<MySqlForumContext> options) : base(options) { } public DbSet<Topic> Topics { get; set; } public DbSet<Post> Posts { get; set; } }
该上下文对象很是简单,只是声明了一个 MySqlForumContext 对象,而后继承自 DbContext ,并将 Topic 和 Post 实体对象映射到该上下文中,这个使用方式和以前的文章中链接 MSSQL 数据库的使用方式是彻底一致的,这点很是可贵,经过 EFCore,不管你链接到的是哪一种类型的数据库,其 API 的使用方式几乎是没有什么不一样的,可让开发人员平滑的过渡。github
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "Mysql.Forum": "server=127.0.0.1;port=3406;uid=root;pwd=root;database=Forum;" } }
原本上面的链接字符串是无需指定端口的,可是由于使用 Pomelo.EntityFrameworkCore.MySql 组件链接 MySql 默认使用的端口是:3306,而我本机上指定端口为 3406,因此仍是须要指定 port=3406。sql
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<MySqlForumContext>(options => { var connectionString = this.Configuration["ConnectionStrings:Mysql.Forum"]; options.UseMySql(connectionString); }); ... }
Add-Migration MySql.Forum.v1数据库
Update-Databse编程
很是完美,到这一步,你已经完成了使用 EFCore 链接到 MariaDB/MySql 数据库的过程,先不要急作各类 CURD 的操做,下面,咱们继续在项目中使用 EFCore 链接 PostgreSQL 数据库,到最后咱们再一块儿作一个 CURD 的 Demojson
PostgreSQL是一个功能强大的开源数据库系统。通过长达15年以上的积极开发和不断改进,PostgreSQL已在可靠性、稳定性、数据一致性等得到了业内极高的声誉。目前PostgreSQL能够运行在全部主流操做系统上,包括Linux、Unix(AIX、BSD、HP-UX、SGI IRIX、Mac OS X、Solaris和Tru64)和Windows。PostgreSQL是彻底的事务安全性数据库,完整地支持外键、联合、视图、触发器和存储过程(并支持多种语言开发存储过程)。它支持了大多数的SQL:2008标准的数据类型,包括整型、数值值、布尔型、字节型、字符型、日期型、时间间隔型和时间型,它也支持存储二进制的大对像,包括图片、声音和视频。PostgreSQL对不少高级开发语言有原生的编程接口,如C/C++、Java、.Net、Perl、Python、Ruby、Tcl 和ODBC以及其余语言等,也包含各类文档api
以上介绍来自 PostgreSQL 中文社区:http://www.postgres.cn/v2/about,本人公司的主要业务也是基于 .NetCore+MySql+PostgreSQL,在使用 PostgreSQL 的过程当中,发现 PostgreSQL 真的是一个很是强大的数据库,对咱们的业务带来很是大的帮助,但愿你们都能深刻的了解和使用 PostgreSQL
public class NPgSqlForumContext : DbContext { public NPgSqlForumContext(DbContextOptions<NPgSqlForumContext> options) : base(options) { } public DbSet<Topic> Topics { get; set; } public DbSet<Post> Posts { get; set; } }
有没有发现,上下文对象 NPgSqlForumContext 的结构和上面的 MySqlForumContext 几乎是如出一辙的
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "Mysql.Forum": "server=127.0.0.1;port=3406;uid=root;pwd=root;database=Forum;", "Pgsql.Forum": "server=127.0.0.1;port=5432;uid=postgres;pwd=postgres;database=Forum;" } }
注意:PostgreSQL 的侦听的默认端口是:5432
public void ConfigureServices(IServiceCollection services) { // MariaDB/MySql 上下文初始化 services.AddDbContext<MySqlForumContext>(options => { var connectionString = this.Configuration["ConnectionStrings:Mysql.Forum"]; options.UseMySql(connectionString); }); // PostgreSQL 上下文初始化 services.AddDbContext<NPgSqlForumContext>(options => { var connectionString = this.Configuration["ConnectionStrings:Pgsql.Forum"]; options.UseNpgsql(connectionString); }); ... }
Add-Migration PostgreSQL.Forum.v1 -Context NPgSqlForumContext
Update-Database -Context NpgSqlForumContext
== 注意:这里的建立数据库命令和上面建立 MariaDB/MySql 的命令有一点小小的不一样 ==
由于咱们如今是在一个项目里面使用多个上下文对象,在建立 Migrations 的时候, EF 会自动查找匹配的 Context ,可是,因为使用了多个 Context,在执行命令时,必须指定 -Context NpgSqlForumContext,不然,将抛出 More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands. 的异常。
到这里,咱们已经完成了使用 EFCore 链接到 PostgreSQL 的过程,在 PostgreSQL 中,因为没有指定 Schema ,因此默认数据表会被放在 Schema public 下面,有关更多 PostgreSQL 的 Schema ,请移步官网进一步了解,若是但愿在建立数据库的过程当中指定 Schema ,能够在实体对象 Topic中应用特性 TableAttribute 进行标记便可,也能够手动修改 Migrations 文件,像下面这样
[Table("topic",Schema ="blogs")] public class Topic { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public DateTime CreateTime { get; set; } public ICollection<Post> Posts { get; set; } }
// 代码片断,仅须要增长指定 schema:"blogs" 便可 migrationBuilder.CreateTable( name: "Topics", schema: "blogs", columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), Title = table.Column<string>(nullable: true), Content = table.Column<string>(nullable: true), CreateTime = table.Column<DateTime>(nullable: false) }, constraints: table => { table.PrimaryKey("PK_Topics", x => x.Id); });
在 Ron.OtherDB 项目中,咱们一共建立了两个 Context ,分别是 MySqlForumContext 和 NPgSqlForumContext,这两个 Context 能够在项目中一块儿使用,互不影响
private MySqlForumContext mysqlContext; private NPgSqlForumContext pgsqlContext; public HomeController(MySqlForumContext mysqlContext, NPgSqlForumContext pgsqlContext) { this.mysqlContext = mysqlContext; this.pgsqlContext = pgsqlContext; } `` > 注入的方式很是简单,和其它类型的注入使用方式没有区别,就是简单的在 HomeController 的构造函数中声明这两个 Context 对象便可 #####3.2 使用两个上下文对象进行 CURD 操做 > 下面将演示使用 MySqlForumContext 和 NPgSqlForumContext 进行简单的 CURD 操做,这个操做过程和上一篇的 MSSQL 几乎是彻底相同的,代码比较简单,就直接贴上来了
[Route("api/[controller]"), ApiController] public class HomeController : ControllerBase { private MySqlForumContext mysqlContext; private NPgSqlForumContext pgsqlContext; public HomeController(MySqlForumContext mysqlContext, NPgSqlForumContext pgsqlContext) { this.mysqlContext = mysqlContext; this.pgsqlContext = pgsqlContext; } [HttpGet] public ActionResult Get() { // MySql var mysqlTopics = this.mysqlContext.Topics.ToList(); // PgSql var pgsqlTopics = this.pgsqlContext.Topics.ToList(); return new JsonResult(new { mysql = mysqlTopics, pgsql = pgsqlTopics }); } [HttpPost] public async Task Post([FromBody] TopicViewModel model) { // MySql this.mysqlContext.Topics.Add(new Topic() { Content = model.Content, CreateTime = DateTime.Now, Title = model.Title }); await this.mysqlContext.SaveChangesAsync(); // PgSql this.pgsqlContext.Topics.Add(new Topic() { Content = model.Content, CreateTime = DateTime.Now, Title = model.Title }); await this.pgsqlContext.SaveChangesAsync(); } [HttpPut] public async Task Put([FromBody] TopicViewModel model) { // MySql var topic = this.mysqlContext.Topics.Where(f => f.Id == model.Id).FirstOrDefault(); topic.Title = model.Title; topic.Content = model.Content; await this.mysqlContext.SaveChangesAsync(); // PgSql var pgTopic = this.pgsqlContext.Topics.Where(f => f.Id == model.Id).FirstOrDefault(); pgTopic.Title = model.Title; pgTopic.Content = model.Content; await this.pgsqlContext.SaveChangesAsync(); } [HttpDelete("{id}")] public async Task Delete(int id) { // MySql var topic = this.mysqlContext.Topics.Where(f => f.Id == id).FirstOrDefault(); this.mysqlContext.Topics.Remove(topic); await this.mysqlContext.SaveChangesAsync(); // PgSql var pgTopic = this.pgsqlContext.Topics.Where(f => f.Id == id).FirstOrDefault(); this.pgsqlContext.Topics.Remove(pgTopic); await this.pgsqlContext.SaveChangesAsync(); } }
```
从结果中能够看到,代码执行正常完成,至此,本文完成
经过本文学习,咱们掌握了如下能力
https://github.com/lianggx/EasyAspNetCoreDemo/tree/master/Ron.OtherDB