在上一篇文章中(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