欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

程序员文章站 2022-04-08 21:26:40
在本章中,将继续介绍如何利用 EFCore 连接到 MariaDB/MySql 和 PostgreSQL 数据库,同时,在一个项目中,如何添加多个数据库上下文对象,并在业务中使用多个上下文对象,通过这两章的学习,你将掌握使用 EFCore 连接 MSSQL/MariaDB/MySql/Postgre... ......

前言

在上一篇文章中(asp.net core 轻松学-10分钟使用efcore连接mssql数据库)[],介绍了 efcore 连接 mssql 的使用方法,在本章中,将继续介绍如何利用 efcore 连接到 mariadb/mysql 和 postgresql 数据库,同时,在一个项目中,如何添加多个数据库上下文对象,并在业务中使用多个上下文对象,通过这两章的学习,你将掌握使用 efcore 连接 mssql/mariadb/mysql/postgresql 的能力。在 .netcore 的时代,由于其设计的独特性(区别于.netframework),使得我们非常容易的使用各种开源的、跨平台的产品和中间件,作为普通程序员,通过广泛参与和使用开源产品,是我们义不容辞的责任和义务,这种行为将进一步的扩大 .net core 的生态圈,进而影响整个开发行业。闲话说完,进入今天的正题,连接第三方数据库和支持多个上下文对象。

1. 使用 mariadb/mysql 数据库

mariadb基于mysql并遵循gpl v2授权使用的。 她是由以monty program ab为主要管理者的mariadb社区开发的。mariadb与另一分支mysql最新版保持同步更新。在mariadb工作与在mysql下工作几乎一模一样,她们有相同的命令、界面,以及在mysql中的库与api,所以mariadb可以说是为替换mysql量身定做的,所以它们之间是相通用(兼容),换用后连数据库都不必转换并可以获得mariadb提供的许多更好的新特性。
以上介绍来自官方文档

1.1

首先创建一个 asp.net core webapi 2.2 的项目 ron.otherdb,并从 nuget 仓库引用包 pomelo.entityframeworkcore.mysql,我本地安装的数据库是 mariadb,从介绍中得知,mariadb 和 mysql 的使用方式几乎是完全一致的,所以这里使用 pomelo.entityframeworkcore.mysql 连接 mariadb 也是没有任何问题的

1.2 项目结构和包引用如下

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

1.3 编写业务实体

下面将编写两个业务实体 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; }
    }
1.4 编写上下文对象
    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 的使用方式几乎是没有什么不同的,可以让开发人员平滑的过渡。

1.5 在 appsetting.json 中配置数据库连接字符串
{
  "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。

1.6 在 startup.cs 中初始化上下文对象
        public void configureservices(iservicecollection services)
        {
            services.adddbcontext<mysqlforumcontext>(options =>
            {
                var connectionstring = this.configuration["connectionstrings:mysql.forum"];
                options.usemysql(connectionstring);
            });
            ...
        }
1.7 创建 migrations 对象
  • 在包管理器控制台输入以下命令,创建 migrations 对象

add-migration mysql.forum.v1

  • 继续在包管理器控制台中输入以下命令,该命令将会在数据库中创建实体业务对象 topic/post 映射的数据表

update-databse

  • 打开 mariadb ,可以看到,数据库已经成功创建

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

非常完美,到这一步,你已经完成了使用 efcore 连接到 mariadb/mysql 数据库的过程,先不要急做各种 curd 的操作,下面,我们继续在项目中使用 efcore 连接 postgresql 数据库,到最后我们再一起做一个 curd 的 demo

2. 使用 postgresql 数据库

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以及其他语言等,也包含各种文档

以上介绍来自 postgresql 中文社区: .netcore+mysql+postgresql,在使用 postgresql 的过程中,发现 postgresql 真的是一个非常强大的数据库,对我们的业务带来非常大的帮助,希望大家都能深入的了解和使用 postgresql

2.1 首先还是在项目中引用 npgsql.entityframeworkcore.postgresql 包

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

2.2 编写上下文对象 npgsqlforumcontext
    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 几乎是一模一样的

2.3 在配置文件中增加 postgresql 的连接字符串
{
  "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

2.4 在 startup.cs 中初始化上下文对象
        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);
            });

            ...
        }
2.5 创建 migrations for postgresql 对象
  • 这里创建 migrations 的方式和上面的创建 migrations for mariadb/mysql 的方式是一样的,在项目包管理器控制台中输入以下命令,创建 migrations 对象后直接创建数据库

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. 的异常。

  • 打开 postgresql 管理工具,发现数据库 forum 已经成功创建,表结构和 mariadb/mysql 中创建的 forum 数据库表完全一致,使用的都是同一个实体业务对象 topic/post

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

到这里,我们已经完成了使用 efcore 连接到 postgresql 的过程,在 postgresql 中,由于没有指定 schema ,所以默认数据表会被放在 schema public 下面,有关更多 postgresql 的 schema ,请移步官网进一步了解,如果希望在创建数据库的过程中指定 schema ,可以在实体对象 topic中应用特性 tableattribute 进行标记即可,也可以手动修改 migrations 文件,像下面这样

  • 使用特性 tableattribute 进行标记
    [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; }
    }
  • 手动修改 migrations 文件 migrations/20190119035709_postgresql.forum.v1.cs
//  代码片段,仅需要增加指定 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);
                });

3. 在项目中使用多个上下文

在 ron.otherdb 项目中,我们一共创建了两个 context ,分别是 mysqlforumcontext 和 npgsqlforumcontext,这两个 context 可以在项目中一起使用,互不影响

3.1 在 homecontroller 注入两个 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();
    }
}

```

3.3 打开控制台执行 dotnet run

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

3.4 分别调用 中的 get/post/put/delete 接口,可以看到,数据库中可以正常添加和修改数据
  • mariadb/mysql 数据库结果

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

  • postgresql 数据库结果

Asp.Net Core 轻松学-使用MariaDB/MySql/PostgreSQL和支持多个上下文对象

从结果中可以看到,代码执行正常完成,至此,本文完成

结束语

通过本文学习,我们掌握了以下能力

  • 如何在 asp.netcore 中使用 efcore 连接使用 mariadb/mysql/postgresql 数据库,
  • 如何创建多个 migrations 对象
  • 如何在项目中使用多个不同的上下文对象

演示代码下载

https://github.com/lianggx/easyaspnetcoredemo/tree/master/ron.otherdb