• .NET Core MongoDB数据仓储和工作单元模式实操


    前言

      上一章节我们主要讲解了MongoDB数据仓储和工作单元模式的封装,这一章节主要讲的是MongoDB用户管理相关操作实操。如:获取所有用户信息、获取用户分页数据、通过用户ID获取对应用户信息、添加用户信息、事务添加用户信息、用户信息修改、用户信息删除等实战教程。

    MongoDB从入门到实战的相关教程

    MongoDB从入门到实战之MongoDB简介👉

    MongoDB从入门到实战之MongoDB快速入门👉

    MongoDB从入门到实战之Docker快速安装MongoDB👉

    MongoDB从入门到实战之MongoDB工作常用操作命令👉

    MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建👉

    MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成👉

    MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(3)-系统数据集合设计👉

    MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(4)-MongoDB数据仓储和工作单元模式封装👉

    MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(5)-MongoDB数据仓储和工作单元模式实操👉

    YyFlight.ToDoList项目源码地址

    欢迎各位看官老爷review,有帮助的别忘了给我个Star哦💖!!!

    GitHub地址:https://github.com/YSGStudyHards/YyFlight.ToDoList

    MongoRepository地址:https://github.com/YSGStudyHards/YyFlight.ToDoList/tree/main/Repository/Repository

    MongoDB事务使用前提说明

    参阅MongoDB的事务

    说明:

    MongoDB单机服务器不支持事务【使用MongoDB事务会报错:Standalone servers do not support transactions】,只有在集群情况下才支持事务,因为博主接下来都是在单机环境下操作,所以无法来演示Mongo事务操作,但是方法都已经是封装好了的,大家可以自己搭建集群实操。

    原因:

    MongoDB在使用分布式事务时需要进行多节点之间的协调和通信,而单机环境下无法实现这样的分布式协调和通信机制。但是,在MongoDB部署为一个集群(cluster)后,将多个计算机连接为一个整体,通过协调和通信机制实现了分布式事务的正常使用。从数据一致性和可靠性的角度来看,在分布式系统中实现事务处理是至关重要的。而在单机环境下不支持事务,只有在集群情况下才支持事务的设计方式是为了保证数据一致性和可靠性,并且也符合分布式系统的设计思想。

    创建EntityBase公共类

    一个公共的具有相同特性和行为的基类。

    复制代码
        public class EntityBase
        {
            /// 
            /// 主键Id
            /// 
            [BsonId]
            [BsonRepresentation(BsonType.ObjectId)]
            public string Id { get; set; }
    
            /// 
            /// 创建时间
            /// 
            public DateTime CreateDate { get; set; }
    
            /// 
            /// 更新时间
            /// 
            public DateTime UpdateDate { get; set; }
        }
    复制代码

    添加UserInfo用户表实体映射模型

    复制代码
        [Table("yyflight_todolist_user")]
        public class UserInfo : EntityBase
        {
            /// 
            /// 登录账号
            /// 
            public string UserName { get; set; }
    
            /// 
            /// 登录密码
            /// 
    
            public string Password { get; set; }
    
            /// 
            /// 用户昵称
            /// 
            public string NickName { get; set; }
    
            /// 
            /// 用户头像
            /// 
            public string HeadPortrait { get; set; }
    
            /// 
            /// 用户邮箱
            /// 
            public string Email { get; set; }
    
            /// 
            /// 用户状态(0冻结,1正常,2注销)
            /// 
            public int Status { get; set; }
        }
    复制代码

    在前面类中,Id属性中的特性的作用:

    • 需要用于将通用语言运行时(CLR)对象映射到MongoDB集合。
    • [BsonId]进行注释,使该属性成为文档的主键。
    • [BsonRepresentation(BsonType.ObjectId)]进行注释,以允许以字符串类型而不是ObjectId结构传递参数。Mongo处理从字符串到ObjectId的转换。没有此特性序列化时会有如下异常提示:

    System.FormatException: An error occurred while deserializing the Id property of class Repository.Domain.User.UserInfo: Cannot deserialize a 'String' from BsonType 'ObjectId'.

    知识拓展MongoDB ObjectId类型概述:

    每次插入一条数据系统都会自动插入一个_id键,键值不可以重复,它可以是任何类型的,也可以手动的插入,默认情况下它的数据类型是ObjectId,由于MongoDB在设计之初就是用作分布式数据库,所以使用ObjectId可以避免不同数据库中_id的重复(如果使用自增的方式在分布式系统中就会出现重复的_id的值)。
    ObjectId使用12字节的存储空间,每个字节可以存储两个十六进制数字,所以一共可以存储24个十六进制数字组成的字符串,在这24个字符串中,前8位表示时间戳,接下来6位是一个机器码,接下来4位表示进程id,最后6位表示计数器。

    MongoDB 采用 ObjectId 来表示主键的类型,数据库中每个文档都拥有一个_id 字段表示主键,_id 的生成规则如下:

    其中包括4-byte Unix 时间戳,3-byte 机器 ID,2-byte 进程 ID,3-byte 计数器(初始化随机)

    1
    2
    3
    601e2b6b  a3203c  c89f   2d31aa
       ↑        ↑       ↑       ↑
     时间戳    机器码   进程ID   随机数 

    创建用户Repository

    创建用户IUserRepository接口

        public interface IUserRepository : IMongoRepository
        {
        }

    创建用户UserRepository类

    复制代码
        public class UserRepository : MongoBaseRepository, IUserRepository
        {
            public UserRepository(IMongoContext context) : base(context)
            {
            }
        }
    复制代码

    创建用户管理业务代码

    创建IUserOperationExampleServices接口

    复制代码
        public interface IUserOperationExampleServices
        {
            /// 
            /// 获取所有用户信息
            /// 
            /// 
            Task> GetAllUserInfos();
    
            /// 
            /// 用户分页数据获取
            /// 
            /// userInfoByPageListReq
            /// 
            Task> GetUserInfoByPageList(UserInfoByPageListReq userInfoByPageListReq);
    
            /// 
            /// 通过用户ID获取对应用户信息
            /// 
            /// id
            /// 
            Task GetUserInfoById(string id);
    
            /// 
            /// 添加用户信息
            /// 
            /// userInfo
            /// 
            Task AddUserInfo(UserInfoReq userInfo);
    
            /// 
            /// 事务添加用户信息
            /// 
            /// userInfo
            /// 
            Task AddUserInfoTransactions(UserInfoReq userInfo);
    
            /// 
            /// 用户信息修改
            /// 
            /// id
            /// userInfo
            /// 
            Task UpdateUserInfo(string id, UserInfoReq userInfo);
    
            /// 
            /// 用户信息删除
            /// 
            /// id
            /// 
            Task<bool> Delete(string id);
        }
    复制代码

    创建UserOperationExampleServices类

    复制代码
        public class UserOperationExampleServices : IUserOperationExampleServices
        {
            private readonly IUnitOfWork _unitOfWork;
            private readonly IUserRepository _userRepository;
    
            /// 
            /// 依赖注入
            /// 
            /// unitOfWork
            /// userRepository
            public UserOperationExampleServices(IUnitOfWork unitOfWork, IUserRepository userRepository)
            {
                _unitOfWork = unitOfWork;
                _userRepository = userRepository;
            }
    
            /// 
            /// 获取所有用户信息
            /// 
            /// 
            public async Task> GetAllUserInfos()
            {
                var getAllUserInfos = await _userRepository.GetAllAsync();
                return getAllUserInfos;
            }
    
            /// 
            /// 用户分页数据获取
            /// 
            /// userInfoByPageListReq
            /// 
            public async Task> GetUserInfoByPageList(UserInfoByPageListReq request)
            {
                //创建查询条件构造器
                FilterDefinitionBuilder buildFilter = Builders.Filter;
                FilterDefinition filter = buildFilter.Empty;
                SortDefinition sort = Builders.Sort.Ascending(m => m.CreateDate);
                if (!string.IsNullOrEmpty(request.NickName))
                {
                    filter = buildFilter.Eq(m => m.NickName, request.NickName);
                }
    
                if (!string.IsNullOrEmpty(request.Id))
                {
                    filter = buildFilter.Eq(m => m.Id, request.Id);
                }
    
                var list = await _userRepository.FindListByPageAsync(filter, request.PageIndex, request.PageSize, Array.Empty<string>(), sort);
                return list;
            }
    
            /// 
            /// 通过用户ID获取对应用户信息
            /// 
            /// id
            /// 
            public async Task GetUserInfoById(string id)
            {
                var getUserInfo = await _userRepository.GetByIdAsync(id);
                return getUserInfo;
            }
    
            /// 
            /// 添加用户信息
            /// 
            /// userInfo
            /// 
            public async Task AddUserInfo(UserInfoReq userInfo)
            {
                var addUserInfo = new UserInfo()
                {
                    Id = ObjectId.GenerateNewId().ToString(),
                    UserName = userInfo.UserName,
                    Email = userInfo.Email,
                    NickName = userInfo.NickName,
                    Password = MD5Helper.MDString(userInfo.Password),
                    Status = 1,
                    HeadPortrait = userInfo.HeadPortrait,
                    CreateDate = DateTime.Now,
                    UpdateDate = DateTime.Now,
                };
                await _userRepository.AddAsync(addUserInfo);
                var queryUserInfo = await _userRepository.GetByIdAsync(addUserInfo.Id);
                return queryUserInfo;
            }
    
            /// 
            /// 事务添加用户信息
            /// 
            /// userInfo
            /// 
            public async Task AddUserInfoTransactions(UserInfoReq userInfo)
            {
                using var session = await _unitOfWork.InitTransaction();
                var addUserInfo = new UserInfo()
                {
                    Id = ObjectId.GenerateNewId().ToString(),
                    UserName = userInfo.UserName,
                    Email = userInfo.Email,
                    NickName = userInfo.NickName,
                    Password = MD5Helper.MDString(userInfo.Password),
                    Status = 1,
                    HeadPortrait = userInfo.HeadPortrait,
                    CreateDate = DateTime.Now,
                    UpdateDate = DateTime.Now,
                };
                await _userRepository.AddTransactionsAsync(session, addUserInfo);
    
                //查不到任何信息
                var queryUserInfo = await _userRepository.GetByIdAsync(addUserInfo.Id);
    
                //提交新增用户信息操作
                await _unitOfWork.Commit(session);
    
                //UserInfo只有在提交后才会被添加
                queryUserInfo = await _userRepository.GetByIdAsync(addUserInfo.Id);
    
                return queryUserInfo;
            }
    
            /// 
            /// 用户信息修改
            /// 
            /// id
            /// userInfo
            /// 
            public async Task UpdateUserInfo(string id, UserInfoReq userInfo)
            {
                #region 指定字段和条件修改
    
                //修改条件
                var list = new List>
                {
                    Builders.Filter.Eq("_id", new ObjectId(id))
                };
                var filter = Builders.Filter.And(list);
    
                //指定要修改的字段内容
                //参考文章:https://chsakell.gitbook.io/mongodb-csharp-docs/crud-basics/update-documents
                var updateDefinition = Builders.Update.
                    Set(u => u.HeadPortrait, userInfo.HeadPortrait).
                    Set(u => u.NickName, userInfo.NickName).
                    Set(u => u.Status, userInfo.Status);
    
                await _userRepository.UpdateAsync(filter, updateDefinition);
    
                #endregion
    
                #region 指定对象异步修改一条数据
    
                //var updateUserInfo = new UserInfo
                //{
                //    UserName = userInfo.UserName,
                //    Password = MD5Helper.MDString(userInfo.Password),
                //    Status = 1,
                //    HeadPortrait = userInfo.HeadPortrait,
                //    Email = userInfo.Email,
                //    NickName = userInfo.NickName,
                //    UpdateDate = DateTime.Now,
                //};
                //await _userRepository.UpdateAsync(updateUserInfo, id);
    
                #endregion
    
                #region 数据批量修改示例
    
                ////1.批量修改的条件(把创建时间CreateDate为近五日的用户状态更改为0)
                //var time = DateTime.Now;
                //var list = new List>();
                //list.Add(Builders.Filter.Gt("CreateDate", time));//大于当前时间
                //list.Add(Builders.Filter.Lt("CreateDate", time.AddDays(5)));//小于当前时间+5day
                //var filter = Builders.Filter.And(list);
    
                ////2.要修改的字段内容
                //var dic = new Dictionary
                //{
                //    { "Status", "0" }
                //};
    
                ////3.批量修改
                //await _userRepository.UpdateManayAsync(dic, filter);
    
                #endregion
    
                return await _userRepository.GetByIdAsync(id);
            }
    
            /// 
            /// 用户信息删除
            /// 
            /// 
            /// 
            public async Task<bool> Delete(string id)
            {
                await _userRepository.DeleteAsync(id);
                var testUserInfo = await _userRepository.GetByIdAsync(id);
                return testUserInfo == null;
            }
        }
    复制代码

    UserOperationExample控制创建

    复制代码
        /// 
        /// MongoDB用户管理操作示例
        /// 
        [ApiController]
        [Produces("application/json")]
        [Route("api/[controller]/[action]")]
        public class UserOperationExampleController : ControllerBase
        {
            private readonly IUserOperationExampleServices _userOperationExampleServices;
    
            /// 
            /// 依赖注入
            /// 
            /// userOperationExampleServices
            public UserOperationExampleController(IUserOperationExampleServices userOperationExampleServices)
            {
                _userOperationExampleServices = userOperationExampleServices;
            }
    
            /// 
            /// 获取所有用户信息
            /// 
            /// 
            [HttpGet]
            public async Task>> GetAllUserInfos()
            {
                var userInfos = await _userOperationExampleServices.GetAllUserInfos();
                return Ok(userInfos);
            }
    
            /// 
            /// 获取用户分页数据
            /// 
            /// userInfoByPageListReq
            /// 
            [HttpPost]
            public async Task>> GetUserInfoByPageList([FromBody] UserInfoByPageListReq userInfoByPageListReq)
            {
                var getUserInfoByPageList = await _userOperationExampleServices.GetUserInfoByPageList(userInfoByPageListReq);
                return Ok(getUserInfoByPageList);
            }
    
            /// 
            /// 通过用户ID获取对应用户信息
            /// 
            /// id
            /// 
            [HttpGet("{id}")]
            public async Task> GetUserInfoById(string id)
            {
                var userInfo = await _userOperationExampleServices.GetUserInfoById(id);
                return Ok(userInfo);
            }
    
            /// 
            /// 添加用户信息
            /// 
            /// userInfo
            /// 
            [HttpPost]
            public async Task> AddUserInfo([FromBody] UserInfoReq userInfo)
            {
                var addUserInfo = await _userOperationExampleServices.AddUserInfo(userInfo);
                return Ok(addUserInfo);
            }
    
            /// 
            /// 事务添加用户信息
            /// 
            /// userInfo
            /// 
            [HttpPost]
            public async Task> AddUserInfoTransactions([FromBody] UserInfoReq userInfo)
            {
                //TODO:单机服务器不支持事务使用【使用MongoDB事务会报错:Standalone servers do not support transactions】,只有在集群情况下才能用
                var addUserInfo = await _userOperationExampleServices.AddUserInfoTransactions(userInfo);
                return Ok(addUserInfo);
            }
    
            /// 
            /// 用户信息修改
            /// 
            /// id
            /// userInfo
            /// 
            [HttpPut("{id}")]
            public async Task> UpdateUserInfo(string id, [FromBody] UserInfoReq userInfo)
            {
                var updateUserInfo = await _userOperationExampleServices.UpdateUserInfo(id, userInfo);
                return Ok(updateUserInfo);
            }
    
            /// 
            /// 用户信息删除
            /// 
            /// id
            /// 
            [HttpDelete("{id}")]
            public async Task Delete(string id)
            {
                var deleteUser = await _userOperationExampleServices.Delete(id);
                return Ok(deleteUser);
            }
        }
    复制代码

    注册数据库基础操作和工作单元

    //注册数据库基础操作和工作单元
    builder.Services.AddScoped();
    builder.Services.AddScoped();
    builder.Services.AddScoped();

    注册相关应用服务

    builder.Services.AddScoped();

    Swagger用户管理操作示例展示

    添加用户信息

     添加成功,返回添加成功的用户信息:

    通过用户ID获取对应用户信息

    拿刚才添加成功的用户ID,查询用户信息:

    获取所有用户信息

    用户分页数据获取

    查询第1页,显示10条数据:

    查询第1页,显示2条数据:

     

     用户信息修改

    指定要修改的字段内容,修改HeadPortrait、NickName、Status
    参考文章:https://chsakell.gitbook.io/mongodb-csharp-docs/crud-basics/update-documents

     

     修改成功:

    用户信息删除

    输入需要删除的用户ID,点击Execute删除:

     

  • 相关阅读:
    JAVA麦克风实时录音调用听写并存储音频到本地
    elasticsearch(ES)分布式搜索引擎04——(数据聚合,自动补全,数据同步,ES集群)
    STROBE-MR
    聚焦新一代技术平台,智能低代码平台成为新趋势
    【部分】CCAA审核员-2022年7月OHSMS职业健康安全体系考试真题
    聊聊流式数据湖Paimon(四)
    嵌入式系统日志轮转:实现与性能考量
    SGP.22-V.3.1-安全2
    PhpSpreadsheet设置单元格常用操作汇总
    使用Windbg排查线程死锁引起的连不上服务器问题
  • 原文地址:https://www.cnblogs.com/Can-daydayup/p/17294749.html