34.C#操作MongoDB

34.CSharp操作MongoDB


34.1 知识点

在 C# 中使用 MongoDB,可以通过官方提供的 MongoDB .NET Driver 来操作数据库。

驱动安装

NuGet

在项目中通过 NuGet 安装 MongoDB 的官方 .NET 驱动程序:

Install-Package MongoDB.Driver

或使用 .NET CLI:

dotnet add package MongoDB.Driver


Github仓库

你还可以通过仓库方式安装源代码:

https://github.com/mongodb/mongo-csharp-driver

该方法适合魔改的用户使用。

选择驱动安装方式

个人更加偏向NuGet方式安装,因为这种方式升级相对比较简单,相反源代码升级起来就要麻烦一些。如果没有一些特殊个人定制的取消,建议使用NuGet就可以。

代码中使用MongoDB

创建 MongoDB 数据库和集合

在 MongoDB 中,数据库和集合会在插入数据时自动创建,因此不需要手动创建。

连接到 MongoDB

使用 MongoClient 连接到 MongoDB。

using MongoDB.Driver;

public class MongoDBConnection
{
    private readonly IMongoDatabase _database;

    public MongoDBConnection(string databaseName)
    {
        // MongoDB 默认连接字符串
        var client = new MongoClient("mongodb://localhost:27017");
        _database = client.GetDatabase(databaseName);
    }

    public IMongoCollection<T> GetCollection<T>(string collectionName)
    {
        return _database.GetCollection<T>(collectionName);
    }
}

创建模型类

MongoDB 的集合中的文档通常是 JSON 格式,可以用 C# 类来映射。

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

public class User
{
    [BsonId] // 指定主键
    [BsonRepresentation(BsonType.ObjectId)] // 使用 ObjectId 类型
    public string Id { get; set; }

    [BsonElement("name")] // 指定字段名
    public string Name { get; set; }

    [BsonElement("age")]
    public int Age { get; set; }
}

插入数据

使用 InsertOneInsertMany 方法插入数据。

public void InsertUser()
{
    var dbConnection = new MongoDBConnection("TestDatabase");
    var userCollection = dbConnection.GetCollection<User>("Users");

    var newUser = new User
    {
        Name = "Alice",
        Age = 25
    };

    userCollection.InsertOne(newUser);
    Console.WriteLine("User inserted successfully!");
}

查询数据

使用 Find 方法查询集合中的数据。

public void QueryUsers()
{
    var dbConnection = new MongoDBConnection("TestDatabase");
    var userCollection = dbConnection.GetCollection<User>("Users");

    // 查询所有用户
    var users = userCollection.Find(user => true).ToList();

    foreach (var user in users)
    {
        Console.WriteLine($"ID: {user.Id}, Name: {user.Name}, Age: {user.Age}");
    }

    // 条件查询(如查询年龄大于 20 的用户)
    var filteredUsers = userCollection.Find(user => user.Age > 20).ToList();

    foreach (var user in filteredUsers)
    {
        Console.WriteLine($"Filtered -> ID: {user.Id}, Name: {user.Name}, Age: {user.Age}");
    }
}

更新数据

使用 ReplaceOneUpdateOne 方法更新数据。

public void UpdateUser(string id)
{
    var dbConnection = new MongoDBConnection("TestDatabase");
    var userCollection = dbConnection.GetCollection<User>("Users");

    var filter = Builders<User>.Filter.Eq(user => user.Id, id);
    var update = Builders<User>.Update.Set(user => user.Age, 30);

    var result = userCollection.UpdateOne(filter, update);
    Console.WriteLine($"{result.ModifiedCount} document(s) updated.");
}

删除数据

使用 DeleteOneDeleteMany 方法删除数据。

public void DeleteUser(string id)
{
    var dbConnection = new MongoDBConnection("TestDatabase");
    var userCollection = dbConnection.GetCollection<User>("Users");

    var filter = Builders<User>.Filter.Eq(user => user.Id, id);
    var result = userCollection.DeleteOne(filter);

    Console.WriteLine($"{result.DeletedCount} document(s) deleted.");
}

使用建议

索引优化

为查询频繁的字段创建索引,提高查询性能。

userCollection.Indexes.CreateOne(new CreateIndexModel<User>(
    Builders<User>.IndexKeys.Ascending(user => user.Name)
));

连接池管理

MongoClient 是线程安全的,建议在整个应用程序中复用一个实例,而不是每次都创建新实例。

异常处理

捕获 MongoDB 的异常(如 MongoException),记录日志并妥善处理。


34.2 知识点代码

Program.cs

using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;

namespace MongoDBExample
{
    // 定义 User 类,用于表示 MongoDB 集合中的文档
    // 在 MongoDB 中,数据以文档形式存储,这里用 C# 类来映射这些文档
    public class User
    {
        // [BsonId] 特性指定该属性作为文档的主键
        // 主键是唯一标识每个文档的字段
        [BsonId]
        // [BsonRepresentation(BsonType.ObjectId)] 特性指定该属性在 MongoDB 中以 ObjectId 类型表示
        // ObjectId 是 MongoDB 自动生成的唯一标识符
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

        // [BsonElement("name")] 特性指定该属性在 MongoDB 文档中对应的字段名是 "name"
        // 如果不指定,默认使用属性名作为字段名
        [BsonElement("name")]
        public string Name { get; set; }

        // [BsonElement("age")] 特性指定该属性在 MongoDB 文档中对应的字段名是 "age"
        [BsonElement("age")]
        public int Age { get; set; }
    }

    // 定义 MongoDBConnection 类,用于管理与 MongoDB 的连接
    public class MongoDBConnection
    {
        // 私有字段,用于存储对 MongoDB 数据库的引用
        private readonly IMongoDatabase _database;

        // 构造函数,接受数据库名称作为参数
        public MongoDBConnection(string databaseName)
        {
            // 创建一个 MongoClient 实例,连接到本地 MongoDB 服务器
            // "mongodb://localhost:27017" 是 MongoDB 的默认连接字符串,表示连接到本地的 27017 端口
            var client = new MongoClient("mongodb://localhost:27017");
            // 通过 MongoClient 获取指定名称的数据库
            _database = client.GetDatabase(databaseName);
        }

        // 泛型方法,用于获取指定名称的集合
        // <T> 表示泛型类型参数,这里可以传入不同的类来表示不同的集合文档结构
        public IMongoCollection<T> GetCollection<T>(string collectionName)
        {
            // 从数据库中获取指定名称和类型的集合
            return _database.GetCollection<T>(collectionName);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // 创建 MongoDBConnection 实例,指定数据库名称为 "TestDatabase"
                var dbConnection = new MongoDBConnection("TestDatabase");
                // 从数据库连接中获取名为 "Users" 的集合,集合中的文档结构由 User 类表示
                var userCollection = dbConnection.GetCollection<User>("Users");

                // 为集合中的 Name 字段创建索引
                // 索引可以提高对该字段的查询性能,尤其是在数据量较大时
                userCollection.Indexes.CreateOne(new CreateIndexModel<User>(
                    // 指定索引按照 Name 字段的升序排列
                    Builders<User>.IndexKeys.Ascending(user => user.Name)
                ));

                // 调用插入数据的方法
                InsertData(userCollection);

                // 调用查询数据的方法
                QueryData(userCollection);

                // 调用更新数据的方法
                UpdateData(userCollection);

                // 调用删除数据的方法
                DeleteData(userCollection);
            }
            catch (MongoException ex)
            {
                // 捕获 MongoDB 操作过程中可能抛出的异常
                // 例如网络连接问题、数据库权限问题等
                Console.WriteLine($"MongoDB 操作发生错误: {ex.Message}");
            }
            catch (Exception ex)
            {
                // 捕获其他未知异常
                // 确保程序在遇到异常时不会崩溃,而是输出错误信息
                Console.WriteLine($"发生未知错误: {ex.Message}");
            }

            // 等待用户输入,防止控制台窗口立即关闭
            Console.ReadLine();
        }

        // 插入数据的方法,接受用户集合作为参数
        static void InsertData(IMongoCollection<User> userCollection)
        {
            // 创建一个新的 User 对象
            var newUser = new User
            {
                Name = "Alice",
                Age = 25
            };
            // 调用集合的 InsertOne 方法将新用户插入到集合中
            userCollection.InsertOne(newUser);
            // 输出插入成功的信息
            Console.WriteLine("User inserted.");
        }

        // 查询数据的方法,接受用户集合作为参数
        static void QueryData(IMongoCollection<User> userCollection)
        {
            // 查询集合中的所有用户
            // Find(user => true) 表示查询条件为始终为真,即返回所有文档
            // ToList() 方法将查询结果转换为列表
            var users = userCollection.Find(user => true).ToList();
            // 输出所有用户的信息
            Console.WriteLine("All users:");
            foreach (var user in users)
            {
                Console.WriteLine($"ID: {user.Id}, Name: {user.Name}, Age: {user.Age}");
            }

            // 条件查询,查询年龄大于 20 的用户
            // Find(user => user.Age > 20) 表示查询条件为年龄大于 20
            var filteredUsers = userCollection.Find(user => user.Age > 20).ToList();
            // 输出过滤后的用户信息
            Console.WriteLine("Users older than 20:");
            foreach (var user in filteredUsers)
            {
                Console.WriteLine($"Filtered -> ID: {user.Id}, Name: {user.Name}, Age: {user.Age}");
            }
        }

        // 更新数据的方法,接受用户集合作为参数
        static void UpdateData(IMongoCollection<User> userCollection)
        {
            // 定义更新条件,查找 Name 字段等于 "Alice" 的文档
            var filter = Builders<User>.Filter.Eq(user => user.Name, "Alice");
            // 定义更新操作,将符合条件的文档的 Age 字段更新为 30
            var update = Builders<User>.Update.Set(user => user.Age, 30);
            // 调用集合的 UpdateOne 方法执行更新操作
            // UpdateOne 方法只更新第一个符合条件的文档
            var result = userCollection.UpdateOne(filter, update);
            // 输出更新的文档数量
            Console.WriteLine($"{result.ModifiedCount} document(s) updated.");
        }

        // 删除数据的方法,接受用户集合作为参数
        static void DeleteData(IMongoCollection<User> userCollection)
        {
            // 定义删除条件,查找 Name 字段等于 "Alice" 的文档
            var deleteFilter = Builders<User>.Filter.Eq(user => user.Name, "Alice");
            // 调用集合的 DeleteOne 方法执行删除操作
            // DeleteOne 方法只删除第一个符合条件的文档
            var deleteResult = userCollection.DeleteOne(deleteFilter);
            // 输出删除的文档数量
            Console.WriteLine($"{deleteResult.DeletedCount} document(s) deleted.");
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏