Skip to content

Files

Latest commit

4650f41 · Jan 11, 2022

History

History
323 lines (209 loc) · 11.9 KB

File metadata and controls

323 lines (209 loc) · 11.9 KB

六、C# 基础 MongoDB

多年来,随着 MongoDB 越来越成为主流数据库,大量技术被接受和扩展,因此有可能进行交互。与来自 Java、Microsoft.NET、Node.js 和许多其他平台的 MongoDB 进行交互是非常正常的。

在本章中,我们将讨论如何使用 Microsoft.NET 和 C# 来操作 MongoDB 中的数据。这个想法是展示一些基本的操作(并带来一些构建模块),然后在稍后深入到一个更复杂的解决方案。

为了能够使用来自 Microsoft.NET 的 MongoDB,我们需要一个特定的驱动程序。在本书中,我们将使用 MongoDB 提供的官方驱动程序。

驱动可以从 MongoDB 网站下载。但是,安装驱动程序的首选方法是使用 NuGet 包,该包可通过以下命令获得:

代码清单 52:在 NuGet 上安装 MongoDB 驱动程序

  Install-Package
  MongoDB.Driver

NuGet 上还有其他几个官方(传统)MongoDB 驱动程序可用;但是,前面提到的包是最新支持的,它应该用于任何新项目。在写这本书的时候,驱动的最新版本是 2.4 ,至少需要使用 Microsoft.NET v 4.5;但是,它也支持。NET 核心。

表 15: C# 驱动程序版本

C#/。NET 驱动程序版本 蒙戈布 2.4 蒙戈布 2.6 蒙戈布 3.0 蒙戈布 3.2 蒙戈布 3.4
2.4 版 -好的 -好的
2.3 版 -好的 -好的 -好的 -好的 -好的
2.2 版 -好的 -好的 -好的 -好的

从驱动 2.0 版本开始,就有了对async API 的支持。这个特性允许我们更有效地使用资源。与以前的版本相比,这个版本带来了一个新的、更简化的应用编程接口。例如,现在有Option类允许以这种方式配置不同的重载,而不是重载方法。

驱动程序实现了三个最重要的顶级接口:

表 16: MongoDB 驱动程序的主要接口

| IMongoClient | 定义将与 MongoDB 服务器交互的根对象。负责连接、监控和对服务器执行操作。 | | IMongoDatabase | 表示 MongoDB 服务器实例中的database。 | | IMongoCollection | 表示 MongoDB 数据库中的一个collection。 |

在接下来的章节中,我们将看看如何使用实现上述接口的类。

连接到数据库

在本章中,您将学习如何连接到 MongoDB 数据库并执行基本操作,如引用、创建和删除(删除)数据库。

连接到数据库非常简单,它包括使用MongoClient的一个实例。

| | 注意:正如我们在前面几章中看到的,除非另外配置,否则默认情况下 MongoDB 在端口 27017 上运行。 |

首先要做的是直接在 Visual Studio 中运行Install-Package MongoDB.Driver,使用包管理器控制台,安装 MongoDB C# 驱动。

最简单的方法,不使用任何额外的设置,就是创建一个MongoClient类的实例,并将connectionString作为参数传递。请注意,配置字符串的格式为“mongodb://servername:port”。

代码清单 53:在没有身份验证的情况下连接到 MongoDB

  using System;
  using MongoDB.Driver;

  public static void ConnectWithoutAuthentication()
  {
      string connectionString = "mongodb://localhost:27017";

      MongoClient client = new MongoClient(connectionString);

      Console.WriteLine("Connected"); 
  }

连接字符串可以包含相当多的参数,例如在我们使用 MongoDB 集群的情况下的主机列表,或者指定连接选项。完整签名如下:

代码清单 54: MongoDB 连接字符串

  mongodb://[username:password@]host1[:port1][,hostN[:portN]]]
  [/[database][?options]]

创建MongoClient的实例会自动创建到 MongoDB 的连接。MongoClient在后台使用一个连接池。

MongoDB 建议每个应用只创建一个MongoClient实例,这样可以更好地重用连接。如果使用控制反转(IoC)框架,则MongoClient实例可以安全地配置为单例生存期。

认证

MongoDB 本身支持多种认证机制,如 SCRAM-SHA-1 、MONGODB-CR、X.509 证书、LDAP Proxy、Kerberos。默认情况下,使用SCRAM-SHA-1。发送用户名和密码就像创建一个MongoCredential实例并提供databaseusernamepassword一样简单,并将其包装在要传递给MongoClientMongoClientSettings实例中。这是可以使用的第二个重载。描述可能比看到行动更复杂,如下所示:

代码清单 55:通过身份验证连接到 MongoDB

  using MongoDB.Driver;

  public static void ConnectWithAuthentication()
  {
      string dbName = "ecommlight";
      string userName = "some_user";
      string password = "pwd";

      var credentials = MongoCredential.CreateCredential(dbName, userName, password);

      MongoClientSettings clientSettings = new MongoClientSettings()
      {
          Credentials = new[] { credentials },
          Server = new MongoServerAddress("localhost", 27017)
      };

      MongoClient client = new MongoClient(clientSettings);

      Console.WriteLine("Connected as {0}", userName);
  }

正如很快提到的,MongoDB 有一个丰富的身份验证机制模型,这远远超出了本书的范围。有关各种身份验证方法的更多详细信息,请参见本文档

数据库操作

通过 MongoDB 驱动程序,可以创建、列出或删除数据库,这将在本节中演示。

引用数据库

创建对数据库的引用是几乎所有数据操作示例都需要的基本操作。MongoDB 中定义的层次结构是:

服务器>数据库>采集>文档>数据

为了得到数据,应该有一个对数据库的引用,然后一路向下。

为了保持示例简单并简化代码,我们将创建一个简单的方法,该方法将返回MongoClient的一个实例,然后使用该实例来代替每次手动创建连接。

代码清单 56:实例化 Mongo 客户端的通用方法

  public static MongoClient GetMongoClient(string hostName)
  {
      string connectionString = string.Format("mongodb://{0}:27017", hostName);
      return new MongoClient(connectionString);
  }

我们使用GetDatabase()方法直接从MongoClient实例获取对数据库的引用,如下所示:

代码清单 57:获取数据库引用的通用方法

  public static IMongoDatabase GetDatabaseReference(string
  hostName, string dbName)
  {
      MongoClient client = GetMongoClient(hostName);
      IMongoDatabase database = client.GetDatabase(dbName);
      return database;
  }

GetDatabase()返回一个实现IMongoDatabase接口的对象,本例中为MongoDatabaseImpl,是具体的实现。

数据库创建

MongoDB 驱动程序没有创建数据库的显式方法,但这可以通过引用数据库来实现,正如我们在GetDatabaseReference方法中看到的那样。

如果数据库名称不存在,MongoDB 驱动程序将在我们第一次向它添加文档时自动创建它,或者简单地创建一个新的集合。

代码清单 58:用 C# 创建一个新的数据库

  public static IMongoDatabase CreateDatabase(string databaseName, string collectionName)
  {
      MongoClient client = GetMongoClient(hostName);
      IMongoDatabase database = client.GetDatabase(databaseName);
      database.CreateCollection(collectionName);
      return database;
  }

我们可以称之为:

代码清单 59:调用 CreateDatabase 方法

  public static void Main(string[] args)
  {
      CreateDatabase("newDatabaseName", "newCollectionName");
  }

获取数据库列表

获取数据库列表很简单。与获取对单个数据库的引用的方式相同,我们可以在MongoClient实例上调用ListDatabases()ListDatabasesAsync(),并获取BsonDocument的实例,该实例将包含服务器上可用数据库的基本信息。这两种方法都会返回一个实现IAsyncCursor的对象实例;然而,Async版本将返回Task<IAsyncCursor>。让我们看一个例子:

代码清单 60:显示可用数据库的列表

  using System;
  using MongoDB.Driver;
  using System.Threading.Tasks;

  public static async Task GetListOfDatabasesAsync()
  {
      MongoClient client = GetMongoClient("localhost");

      Console.WriteLine("Getting the list of databases asynchronously…");
      using (var cursor = await client.ListDatabasesAsync())
      {
          await cursor.ForEachAsync(d => Console.WriteLine(d.ToString()));
      }
  }

  public static void GetListOfDatabasesSync()
  {
      MongoClient client = GetMongoClient("localhost");

      Console.WriteLine("Getting the list of databases synchronously…");
      var databases = client.ListDatabases().ToList();
      databases.ForEach(d => Console.WriteLine(d.GetElement("name").Value));
  }

这种情况下的输出如下:

图 40:通过 C# 返回数据库列表。

我想强调的是,在第一种情况下(我们使用async方法),一个BsonDocument被返回并打印到控制台。由于是 JSON 格式,所以很容易识别。

在第二种情况下,通过使用Console.WriteLine(d.GetElement("name").Value)),我们只返回它的name部分。

删除数据库

要从 MongoDB 服务器中删除数据库,我们从MongoClient对象中调用Drop Database()DropDatabaseAsync()方法。

代码清单 61:删除数据库(同步和异步版本)

  public static void DropDatabase(string databaseName)
  {
      MongoClient client = GetMongoClient("localhost");
      client.DropDatabase(databaseName);
  }

  public static async void DropDatabaseAsync(string databaseName)
  {
      MongoClient client = GetMongoClient("localhost");
      await client.DropDatabaseAsync(databaseName);
  }

处理收藏

正如我们在前面几章中看到的,我们可以通过使用 MongoDB 外壳来列出和操作集合。这也可以通过使用 C# 驱动程序来实现。在下面的示例中,我们将展示如何列出、创建和删除集合。

IMongoDatabase上主要有三种方法可用:

  • CreateCollectionCreateCollectionAsync:如果不可用,创建一个新的集合。
  • ListCollectionsListCollectionsAsync:列出数据库中已经可用的集合。
  • DropCollectionDropCollectionAsync:从给定的数据库中删除(删除)一个集合。

我们可以将CreateListAndDropCollections方法中的所有操作总结如下:

代码清单 62:显示可用集合的列表

  public static void CreateListAndDropCollections(string databaseName)
  {
      var database = GetDatabaseReference(hostName, databaseName);
      var collectionName = "some_collection";

      //create a new collection.
      database.CreateCollection(collectionName);

      //showing the list of collections before deleting.
      ListCollections(hostName, databaseName);

      //delete a collection.
      database.DropCollection(collectionName);

      //showing the list of collections after deleting.
      ListCollections(hostName, databaseName);
  }

  public static void ListCollections(string hostName, string databaseName)
  {
      var database = GetDatabaseReference(hostName, databaseName);

      var collectionsList = database.ListCollections();

      Console.WriteLine("List of collections in the {0} database:", 

  database.DatabaseNamespace);
      foreach (var collection in collectionsList.ToList())
      {
          Console.WriteLine(collection.ToString());
      }
  }

并通过从调用前面的代码:

代码清单 63:调用方法来显示集合

  public static void Main(string[] args)
  {
      var newDatabaseName = "newDbName";

  CreateListAndDropCollections(newDatabaseName);
  }

这种情况下的输出如下:

图 41:可用集合的列表。

请记住,如果集合已经存在,创建集合将导致错误。