Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >.NET MongoDB数据仓储和工作单元模式封装

.NET MongoDB数据仓储和工作单元模式封装

作者头像
郑子铭
发布于 2025-01-22 06:06:19
发布于 2025-01-22 06:06:19
29800
举报
运行总次数:0

一、引言

在.NET开发中,MongoDB作为一种高性能、灵活的NoSQL数据库,常用于存储和管理大量数据。为了更好地组织代码结构,提高开发效率和代码可维护性,可以将数据访问层与业务逻辑层解耦,使用数据仓储(Repository)模式和工作单元(UnitOfWork)模式来封装MongoDB数据库操作。数据仓储模式通过抽象出通用的CRUD方法,使业务逻辑层无需关心数据的存储细节;工作单元模式则负责协调多个仓储操作,统一管理事务,确保数据的一致性。

二、安装MongoDB.Driver

首先,需要安装MongoDB的官方.NET驱动程序MongoDB.Driver。可以通过NuGet包管理器进行安装:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dotnet add package MongoDB.Driver

或者使用Package Manager:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Install-Package MongoDB.Driver

三、定义MongoDB上下文

创建一个MongoDB上下文类,用于封装数据库连接和集合的获取。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public classMongoContext : IDisposable
{
    privatereadonly IMongoDatabase _database;
    privatereadonly MongoClient _client;

    public MongoContext(string connectionString, string databaseName)
    {
        _client = new MongoClient(connectionString);
        _database = _client.GetDatabase(databaseName);
    }

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

    public void Dispose()
    {
        _client.Dispose();
    }
}

这里使用IMongoDatabase接口来获取MongoDB数据库实例,并提供了GetCollection方法来获取指定集合。

四、定义数据仓储接口和实现

数据仓储接口定义了通用的CRUD操作方法,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IRepository<T> where T : class
{
    Task AddAsync(T entity);
    Task<IEnumerable<T>> GetAllAsync();
    Task<T> GetByIdAsync(string id);
    Task UpdateAsync(T entity);
    Task DeleteAsync(string id);
}

然后实现该接口,创建一个具体的仓储类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public classRepository<T> : IRepository<T> whereT : class
{
    privatereadonly IMongoCollection<T> _collection;

    public Repository(IMongoCollection<T> collection)
    {
        _collection = collection;
    }

    public async Task AddAsync(T entity)
    {
        await _collection.InsertOneAsync(entity);
    }

    publicasync Task<IEnumerable<T>> GetAllAsync()
    {
        returnawait _collection.Find(Builders<T>.Filter.Empty).ToListAsync();
    }

    public async Task<T> GetByIdAsync(string id)
    {
        var filter = Builders<T>.Filter.Eq("_id", id);
        returnawait _collection.Find(filter).FirstOrDefaultAsync();
    }

    public async Task UpdateAsync(T entity)
    {
        var filter = Builders<T>.Filter.Eq("_id", entity.GetType().GetProperty("_id").GetValue(entity));
        await _collection.ReplaceOneAsync(filter, entity);
    }

    public async Task DeleteAsync(string id)
    {
        var filter = Builders<T>.Filter.Eq("_id", id);
        await _collection.DeleteOneAsync(filter);
    }
}

这里使用了MongoDB.Driver提供的API来实现具体的CRUD操作。

五、实现工作单元模式

工作单元模式负责协调多个仓储操作,并统一管理事务。定义一个工作单元接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IUnitOfWork : IDisposable
{
    Task<int> CommitAsync();
    void RegisterNew<T>(T entity) where T : class;
    void RegisterModified<T>(T entity) where T : class;
    void RegisterDeleted<T>(T entity) where T : class;
}

然后实现该接口,创建一个工作单元类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public classUnitOfWork : IUnitOfWork
{
    privatereadonly MongoContext _context;
    privatereadonly List<Func<Task>> _commands = new List<Func<Task>>();

    public UnitOfWork(MongoContext context)
    {
        _context = context;
    }

    public async Task<int> CommitAsync()
    {
        using (var session = await _context.Client.StartSessionAsync())
        {
            session.StartTransaction();
            try
            {
                foreach (var command in _commands)
                {
                    await command();
                }
                await session.CommitTransactionAsync();
                return _commands.Count;
            }
            catch (Exception)
            {
                await session.AbortTransactionAsync();
                return0;
            }
            finally
            {
                _commands.Clear();
            }
        }
    }

    publicvoid RegisterNew<T>(T entity) where T : class
    {
        _commands.Add(async () => await _context.GetCollection<T>(typeof(T).Name).InsertOneAsync(entity));
    }

    publicvoid RegisterModified<T>(T entity) where T : class
    {
        var filter = Builders<T>.Filter.Eq("_id", entity.GetType().GetProperty("_id").GetValue(entity));
        _commands.Add(async () => await _context.GetCollection<T>(typeof(T).Name).ReplaceOneAsync(filter, entity));
    }

    publicvoid RegisterDeleted<T>(T entity) where T : class
    {
        var filter = Builders<T>.Filter.Eq("_id", entity.GetType().GetProperty("_id").GetValue(entity));
        _commands.Add(async () => await _context.GetCollection<T>(typeof(T).Name).DeleteOneAsync(filter));
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

这里使用了MongoDB的事务功能来确保多个操作的原子性。

六、使用示例

以下是如何使用封装好的数据仓储和工作单元模式进行数据库操作的示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 创建MongoDB上下文
var context = new MongoContext("mongodb://localhost:27017", "YourDatabaseName");

// 创建工作单元实例
var unitOfWork = new UnitOfWork(context);

// 创建仓储实例
var userRepository = new Repository<User>(context.GetCollection<User>("Users"));

// 添加用户
var newUser = new User { Name = "张三", Email = "zhangsan@example.com" };
unitOfWork.RegisterNew(newUser);

// 更新用户
var userToUpdate = await userRepository.GetByIdAsync("existingUserId");
userToUpdate.Email = "updated@example.com";
unitOfWork.RegisterModified(userToUpdate);

// 删除用户
unitOfWork.RegisterDeleted(new User { Id = "userIdToDelete" });

// 提交事务
await unitOfWork.CommitAsync();

通过这种方式,可以方便地进行数据库的CRUD操作,并且确保了数据的一致性。

七、总结

通过封装.NET MongoDB的数据仓储和工作单元模式,可以有效地解耦业务逻辑层与数据访问层,提高代码的可维护性和可重用性。同时,工作单元模式的引入,使得在处理复杂的业务场景时,能够更好地管理事务,确保数据的一致性和完整性。在实际开发中,可以根据具体需求对这些封装进行扩展和优化,以满足不同的业务需求。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
埋葬这9种过时设计模式!.NET 10 + C#12 的现代化重构指南
曾几何时,某些设计模式是 .NET 优秀架构的基石。我们为 DbContext 包装仓储层,为缓存构建装饰器,精心设计线程安全的单例类。这些模式确实解决过问题——至少在当年如此。
郑子铭
2025/08/24
2110
埋葬这9种过时设计模式!.NET 10 + C#12 的现代化重构指南
实战指南:Dapr + .NET 10 + PostgreSQL + Dapper 构建高效微服务后端
本文向您展示如何将 Dapr 集成到微服务应用程序中并管理服务间的通信。我们将以 POS(销售点)应用后端为例进行演示。
郑子铭
2025/09/02
3150
实战指南:Dapr + .NET 10 + PostgreSQL + Dapper 构建高效微服务后端
.NET Core MongoDB数据仓储和工作单元模式实操
  上一章节我们主要讲解了MongoDB数据仓储和工作单元模式的封装,这一章节主要讲的是MongoDB用户管理相关操作实操。如:获取所有用户信息、获取用户分页数据、通过用户ID获取对应用户信息、添加用户信息、事务添加用户信息、用户信息修改、用户信息删除等实战教程。
追逐时光者
2023/04/17
8870
.NET Core MongoDB数据仓储和工作单元模式实操
.NET Core MongoDB数据仓储和工作单元模式封装
上一章我们把系统所需要的MongoDB集合设计好了,这一章我们的主要任务是使用.NET Core应用程序连接MongoDB并且封装MongoDB数据仓储和工作单元模式,因为本章内容涵盖的有点多关于仓储和工作单元的使用就放到下一章节中讲解了。仓储模式(Repository )带来的好处是一套代码可以适用于多个类,把常用的CRUD通用方法抽象出来通过接口形式集中管理,从而解除业务逻辑层与数据访问层之间的耦合,使业务逻辑层在存储、访问数据库时无须关心数据的来源及存储方式。工作单元模式(UnitOfWork)它是用来维护一个由已经被业务修改(如增加、删除和更新等)的业务对象组成的列表,跨多个请求的业务,统一管理事务,统一提交从而保障事物一致性的作用。
追逐时光者
2023/04/28
1.7K0
ASP.NET 6 使用工作单元操作 MongoDB
最近工作中需要用到MongoDB的事务操作,因此参考了一些资料封装了一个小的组件,提供基础的CRUD Repository基类 和 UnitOfWork工作单元模式。今天,就来简单介绍一下这个小组件。
Edison Zhou
2023/07/21
5220
ASP.NET 6 使用工作单元操作 MongoDB
解锁仓储模式的5大高阶技巧:让.NET开发效率飙升的实战指南
仓储模式(Repository Pattern) 是.NET中流行的设计模式,但人们常常仅将其实现为Entity Framework的简单封装,从而错失了它的真正潜力。
郑子铭
2025/07/29
2930
解锁仓储模式的5大高阶技巧:让.NET开发效率飙升的实战指南
在.Net Core中使用MongoDB的入门教程(二)
在上一篇文章中,讲到了MongoDB在导入驱动、MongoDB的连接,数据的插入等。 在.Net Core中使用MongoDB的入门教程(一) 本篇文章将接着上篇文章进行介绍MongoDB在.Ne
码农阿宇
2018/04/18
9470
在.Net Core中使用MongoDB的入门教程(二)
Repository Pattern已死?深入剖析.NET中的设计模式争议与最佳实践
在.NET生态中,鲜有话题能像 仓储模式(Repository Pattern) 这般引发激烈争论。有些开发者奉其为整洁架构的基石,另一些人则认为它是被Entity Framework Core(EF Core)淘汰的冗余设计。
郑子铭
2025/05/17
2340
Repository Pattern已死?深入剖析.NET中的设计模式争议与最佳实践
.NET 云原生架构师训练营(模块二 基础巩固 MongoDB API实现)--学习笔记
https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi
郑子铭
2021/01/06
3860
.NET 云原生架构师训练营(模块二 基础巩固 MongoDB API实现)--学习笔记
.NET Core开发实战(第29课:定义仓储:使用EF Core实现仓储层)--学习笔记
映射关系,针对每一个领域模型创建一个 EntityTypeConfiguration
郑子铭
2021/01/13
2.7K0
.NET Core开发实战(第29课:定义仓储:使用EF Core实现仓储层)--学习笔记
.NET 9时代革新:四大传统设计模式已成过去式!
伴随每个新版本.NET的发布,微软都在用内置功能重塑软件开发范式。.NET 9延续这一传统,通过强化依赖注入、事件处理、中间件和Entity Framework Core等核心模块,让诸多经典设计模式失去了用武之地。
郑子铭
2025/06/20
1610
.NET 9时代革新:四大传统设计模式已成过去式!
.NET 云原生架构师训练营(模块二 基础巩固 MongoDB API重构)--学习笔记
将业务从controller 抽取到 Lighter.Application 层,并为业务建立抽象接口 Lighter.Application.Contract层
郑子铭
2021/01/07
5680
.NET 云原生架构师训练营(模块二 基础巩固 MongoDB API重构)--学习笔记
.NET Core开发实战(第28课:工作单元模式(UnitOfWork):管理好你的事务)--学习笔记
这两个方法的区别是:一个是返回的 int 是指我们影响的数据条数,另外一个返回 bool 表示我们保存是否成功,本质上这两个方法达到的效果是相同的
郑子铭
2021/01/13
3.9K0
MongoDB Driver 简单的CURD
c#中我们可以使用MongoDB.Driver驱动进行对MongoDB数据库的增删改查.
莫问今朝
2018/08/31
2.1K0
MongoDB Driver 简单的CURD
初识 MongoDB 和 .NET Core 入门
昨天搭建完毕 MongoDB 集群 后,开始计划了解 MongoDB ,并引入使用场景,这里介绍一下学习过程中的一些笔记,帮助读者快速了解 MongoDB 并使用 C# 对其进行编码。
痴者工良
2021/04/26
1.5K0
.NET Core MongoDB的简单使用
使用之前文章提到的MongoDB Compass用法分别添加数据库[myDb]和集合(表)[userinfos]信息,
GoodTime
2024/03/05
5210
.NET Core MongoDB的简单使用
.NET MongoDB Driver 2.2使用示例
说明:mongoDBService是对各种常用操作的封装 public class MongoDBService { #region 变量 /// <summary> /// 缓存 /// </summary> private static ConcurrentDictionary<string, Lazy<MongoClient>> m_mongoClientCache = new Concurren
甜橙很酸
2018/03/08
1.3K0
.NET MongoDB Driver 2.2使用示例
Repository个人实践
  最近,有空了,想着把之前一些乱七八糟的小项目给整理一下,尤其是涉及到Repository、UoW几处。为此,专门查阅了博客园中几个大神 关于Repository的实践,到最后都感觉依然莫衷一是,于是感觉这玩意儿不能深究,自己还是紧扣Martin老爷子关于Repository及UoW的核心定义,自己实践核心概念就是了,其他的都不重要了。
guokun
2020/09/03
1.3K0
Repository个人实践
使用MongoDB在项目中实际运用
一、MongoDB,一个数据库,我们怎么去使用它呢?我们首先了解一下什么是MongoDb
小世界的野孩子
2019/09/11
9340
使用MongoDB在项目中实际运用
.net平台的MongoDB使用
  最近花了点时间玩了下MongoDB.Driver,进行封装了工具库,平常也会经常用到MongoDB,因此写一篇文章梳理知识同时把自己的成果分享给大家。
陈珙
2018/09/12
1K0
.net平台的MongoDB使用
推荐阅读
相关推荐
埋葬这9种过时设计模式!.NET 10 + C#12 的现代化重构指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档