Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >.NET MongoDB数据仓储和工作单元模式封装

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

作者头像
郑子铭
发布于 2025-01-22 06:06:19
发布于 2025-01-22 06:06:19
17600
代码可运行
举报
运行总次数: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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Typora常用命令
1.本教程将使用 Typora 编辑器来讲解 Markdown 的语法,Typora 支持 MacOS 、Windows、Linux 平台,且包含多种主题,编辑后直接渲染出效果。
HammerZe
2022/05/09
5740
Typora常用命令
Markdown语法
Markdown语法 1.标题 一阶标题: # 一阶标题 或 Ctrl+1 二阶标题: # 二阶标题 或 Ctrl+2 三阶标题: # 三阶标题 或 Ctrl+3 四阶标题: # 四阶标题 或 Ctrl+4 五阶标题: # 五阶标题 或 Ctrl+5 六阶标题: # 六阶标题 或 Ctrl+6 2.有序与无序列表 有序:数字+英文小数点(.)+Tab/空格 例:1.+Tab/空格 无序:(+ - *)+Tab/空格 例:-+Tab/空格 3.代码块 1.```+python+回车
changxin7
2019/09/10
7200
Markdown基本语法
Markdown中标题如果想定义一个标题,可以在前面加上#(或者用#将标题括起来)。1-6个#分别表示1-6级标题。有的编辑器需要在#和正文之间加一个空格(Atom),有的编译器不用(MarkdownPad),为了保持同一建议都加上空格。
偏有宸机
2020/11/04
5910
文章编写实用工具——Typora中常用的语法与快捷键
之前给大家分享了Typora、PicGo、Gitee的结合使用教程,看其浏览大家还是比较关注的,下面我就为大家这里了一下日常常用的一些文章编写语法和快捷方式,以便于大家日常使用。
cn華少
2021/11/24
2740
生信星球学习day4-毽子
plot(rnorm(50)) #必应查查plot和runif什么意思图片boxplot(iris$Sepal.Length~iris$Species,col = c("lightblue","lightyellow","lightpink")注:iris是一个R语言自带的数据框,通常用作示例。iris$Sepal.Length表示iris数据框的Sepal.Length这一列数据。以此类推。 生信星球调整字体大小图片1.新建project按红色框框图片设置工作目录:setwd()查看工作目录:getwd(
用户10300841
2023/01/12
4130
Excel图表学习64: 在Excel中仿制“关键影响因素图”
前言:下面的内容是在chandoo.org上学到的制图技术。Chandoo.org是一个很好的网站,上面分享了很多让人耳目一新的Excel技术知识。
fanjy
2019/12/27
4.5K0
Excel图表学习64: 在Excel中仿制“关键影响因素图”
Excel表格中最经典的36个小技巧,全在这儿了
技巧1、单元格内强制换行 技巧2、锁定标题行 技巧3、打印标题行 技巧4、查找重复值 技巧5、删除重复值 技巧6、快速输入对号√ 技巧7、万元显示 技巧8、隐藏0值 技巧9、隐藏单元格所有值。 技巧10、单元格中输入00001 技巧11、按月填充日期 技巧12、合并多个单元格内容 技巧13、防止重复录入 技巧14、公式转数值 技巧15、小数变整数 技巧16、快速插入多行 技巧17、两列互换 技巧18、批量设置求和公式 技巧19、同时查看一个excel文件的两个工作表。 技巧20:同时修改多个工作表 技巧21:恢复未保存文件 技巧22、给excel文件添加打开密码 技巧23、快速关闭所有excel文件 技巧24、制作下拉菜单 技巧25、二级联动下拉 技巧27、删除空白行 技巧28、表格只能填写不能修改 技巧29、文字跨列居中显示 技巧30、批注添加图片 技巧31、批量隐藏和显示批注 技巧32、解决数字不能求和 技巧33、隔行插入空行 技巧34、快速调整最适合列宽 技巧35、快速复制公式 技巧36、合并单元格筛选
Ai学习的老章
2019/09/25
8.7K0
Excel表格中最经典的36个小技巧,全在这儿了
Protel99SE快捷键大全
protel99se快捷键 enter——选取或启动 esc——放弃或取消 f1——启动在线帮助窗口 tab——启动浮动图件的属性窗口 pgup——放大窗口显示比例 pgdn——缩小窗口显示比例 end——刷新屏幕 del——删除点取的元件(1个) ctrl+del——删除选取的元件(2个或2个以上) x+a——取消所有被选取图件的选取状态 x——将浮动图件左右翻转 y——将浮动图件上下翻转 space——将浮动图件旋转90度 crtl+ins——将选取图件复制到编辑区里 shift+ins——将剪贴板里的图件贴到编辑区里 shift+del——将选取图件剪切放入剪贴板里 alt+backspace——恢复前一次的操作 ctrl+backspace——取消前一次的恢复 crtl+g——跳转到指定的位置 crtl+f——寻找指定的文字 alt+f4——关闭prote spacebar——绘制导线,直线或总线时,改变走线模式 v+d——缩放视图,以显示整张电路图 v+f——缩放视图,以显示所有电路部件 home——以光标位置为中心,刷新屏幕 esc——终止当前正在进行的操作,返回待命状态 backspace——放置导线或多边形时,删除最末一个顶点 delete——放置导线或多边形时,删除最末一个顶点 ctrl+tab——在打开的各个设计文件文档之间切换 alt+tab——在打开的各个应用程序之间切换 a——弹出edit\align子菜单 b——弹出view\toolbars子菜单 e——弹出edit菜单 f——弹出file菜单 h——弹出help菜单 j——弹出edit\jump菜单 l——弹出edit\set location makers子菜单 m——弹出edit\move子菜单 o——弹出options菜单 p——弹出place菜单 r——弹出reports菜单 s——弹出edit\select子菜单 t——弹出tools菜单 v——弹出view菜单 w——弹出window菜单 x——弹出edit\deselect菜单 z——弹出zoom菜单 左箭头——光标左移1个电气栅格 shift+左箭头——光标左移10个电气栅格 右箭头——光标右移1个电气栅格 shift+右箭头——光标右移10个电气栅格 上箭头——光标上移1个电气栅格 shift+上箭头——光标上移10个电气栅格 下箭头——光标下移1个电气栅格 shift+下箭头——光标下移10个电气栅格 ctrl+1——以零件原来的尺寸的大小显示图纸 ctrl+2——以零件原来的尺寸的200%显示图纸 ctrl+4——以零件原来的尺寸的400%显示图纸 ctrl+5——以零件原来的尺寸的50%显示图纸 ctrl+f——查找指定字符 ctrl+g——查找替换字符 ctrl+b——将选定对象以下边缘为基准,底部对齐 ctrl+t——将选定对象以上边缘为基准,顶部对齐 ctrl+l——将选定对象以左边缘为基准,靠左对齐 ctrl+r——将选定对象以右边缘为基准,靠右对齐 ctrl+h——将选定对象以左右边缘的中心线为基准,水平居中排列 ctrl+v——将选定对象以上下边缘的中心线为基准,垂直居中排列 ctrl+shift+h——将选定对象在左右边缘之间,水平均布 ctrl+shift+v——将选定对象在上下边缘之间,垂直均布 f3——查找下一个匹配字符 shift+f4——将打开的所有文档窗口平铺显示 shift+f5——将打开的所有文档窗口层叠显示 shift+单左鼠——选定单个对象 crtl+单左鼠,再释放crtl——拖动单个对象 shift+ctrl+左鼠——移动单个对象 按ctrl后移动或拖动——移动对象时,不受电器格点限制 按alt后移动或拖动——移动对象时,保持垂直方向 按shift+alt后移动或拖动——移动对象时,保持水平方向 * 顶层与底层之间层的切换 + (-) 逐层切换:“+”与“-”的方向相反 Q mm(毫米)与mil(密尔)的单位切换 IM 测量两点间的距离 ◎edafans 版权所有,拒绝转载◎exdjavKNu5 E x 编辑X ,X为编辑目标,代号如下:(A)=圆弧;(C)=元件;(F)=填充;(P)=焊盘;(N)=网络;(S)=字符;(T)=导线;(V)=过孔;(I)=连接线;(G)=填充多边形。例如要编辑元件时按E C,鼠标指针出现“十”字,单击要编辑的元件即可进行编辑。 P x 放置 X,X为放置目标,代号同上。 M x 移动X,X为移动目标,(A)、(C)、(F)、(P)、(S)、(T)、(V)、(G)同上,另外( I )=翻转选择部份;(O)旋转选择部份;(M)=移动选择
全栈程序员站长
2022/09/02
2K0
最全Excel 快捷键总结,告别鼠标!
本文为知乎答主宇轩原创,CDA数据分析师已获得授权 这里正在更新完毕最常用的快捷键和最完整的EXCEL快捷键,并且把最有用的都突出显示了。 快捷键的内容分三类: 1.F键:与F1-F12组合快捷键 2.Ctrl组合键 3.其他有用的快捷键 F键常用推荐 F1 :显示“Excel 帮助”任务窗格。(重要) Alt+Shift+F1/Shift+F11 :可插入新的工作表。 Shift+F2 :可添加或编辑单元格批注。(重要) Shift+F3 :显示“插入函数”对话框。 F4 :重复上一个命令或操作,在公
CDA数据分析师
2018/02/24
8.1K0
Typora程序员的记事本.Typora常用快捷操作
a)#→宫格建→加输入内容→回车键,其中#表示标题一,##表示标题二以此类推至######为止
小小咸鱼YwY
2019/07/24
7680
Markdown如何学习,看完这篇文章就够了。
不论是开发者还是写文章的博主。现在主流编辑器是Markdown,所以学习Markdown语法对提升技能很有帮助。想要学习Markdown,这篇文章就够了。
Python兴趣圈
2023/11/10
4700
Markdown如何学习,看完这篇文章就够了。
欢迎使用企业微信文档
企业微信文档是支持多人、多设备协同编辑和实时保存的在线文档。你可以在这里完成个人创作,或与同事一起编辑、讨论,提升协作效率。
深圳夏天
2022/04/08
11.8K0
Markdown的语法介绍+Typora的简单使用
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。
忆想不到的晖
2020/07/15
3.6K0
Markdown的语法介绍+Typora的简单使用
python插件,pycharm基本用法,markdown文本编写,jupyter notebook的基本操作汇总
a)#→宫格建→加输入内容→回车键,其中#表示标题一,##表示标题二以此类推至######为止
小小咸鱼YwY
2019/07/24
3.2K0
工作中必会的57个Excel小技巧
为了方便同学们学习和收藏,兰色把工作中最常用、最简捷的小技巧进行一次整理,共57个。希望对同学们有所帮助。
一朵灼灼华
2022/08/05
4.6K0
20个Excel操作技巧,提高你的数据分析效率
今日头条丨一点资讯丨腾讯丨搜狐丨网易丨凤凰丨阿里UC大鱼丨新浪微博丨新浪看点丨百度百家丨博客中国丨趣头条丨腾讯云·云+社区
数据猿
2019/08/06
2.7K0
最简单上手的Typora使用教程
Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。
用户5928604
2023/10/30
6630
Markdown
因为最近在筹划博客,所以必然离不开写Markdown,这里来总结记录一下,毕竟好久不用了,忘得差不多了~
汐语
2023/02/23
5170
Markdown
Excel 常用的九十九个技巧 Office 自学教程快速掌握办公技巧
Microsoft Excel 是微软为 Windows、macOS、Android 和 iOS 开发的电子表格软件,可以用来制作电子表格、完成许多复杂的数据运算,进行数据的分析和预测,并且具有强大的制作图表的功能。由于 Excel 具有十分友好的人机界面和强大的计算功能,它已成为国内外广大用户管理公司和个人财务、统计数据、绘制各种专业化表格的得力助手。允许用户自定义界面的电子制表软件包括字体、文字属性和单元格格式,它还引进了智能重算的功能,当单元格数据变动时,只有与之相关的数据才会更新,荒岛本次带来九十九个 Excel 技巧,提高您的办公效率。
ximagine
2023/05/05
8.1K0
办公技巧:分享100个Excel快捷键,值得收藏!
85、Ctrl+Shift+Space在数据区域内,为选中当前区域;当前区域无数据时,选中整个工作表
小明互联网技术分享社区
2022/02/17
2.9K0
办公技巧:分享100个Excel快捷键,值得收藏!
推荐阅读
相关推荐
Typora常用命令
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验