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

科技资讯 投稿 8500 0 评论

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

前言

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

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

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

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

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

YyFlight.ToDoList项目源码地址

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

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

MongoDB事务使用前提说明

说明:

原因:

创建EntityBase公共类

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

public class EntityBase { /// <summary> /// 主键Id /// </summary> [BsonId] [BsonRepresentation(BsonType.ObjectId] public string Id { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CreateDate { get; set; } /// <summary> /// 更新时间 /// </summary> public DateTime UpdateDate { get; set; } }

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

    [Table("yyflight_todolist_user"]
    public class UserInfo : EntityBase
    {
        /// <summary>
        /// 登录账号
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 登录密码
        /// </summary>

        public string Password { get; set; }

        /// <summary>
        /// 用户昵称
        /// </summary>
        public string NickName { get; set; }

        /// <summary>
        /// 用户头像
        /// </summary>
        public string HeadPortrait { get; set; }

        /// <summary>
        /// 用户邮箱
        /// </summary>
        public string Email { get; set; }

        /// <summary>
        /// 用户状态(0冻结,1正常,2注销)
        /// </summary>
        public int Status { get; set; }
    }

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

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

知识拓展MongoDB ObjectId类型概述:

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

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

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

创建用户Repository

创建用户IUserRepository接口

    public interface IUserRepository : IMongoRepository<UserInfo>
    {
    }

创建用户UserRepository类

    public class UserRepository : MongoBaseRepository<UserInfo>, IUserRepository
    {
        public UserRepository(IMongoContext context : base(context
        {
        }
    }

创建用户管理业务代码

创建IUserOperationExampleServices接口

    public interface IUserOperationExampleServices
    {
        /// <summary>
        /// 获取所有用户信息
        /// </summary>
        /// <returns></returns>
        Task<IEnumerable<UserInfo>> GetAllUserInfos(;

        /// <summary>
        /// 用户分页数据获取
        /// </summary>
        /// <param name="userInfoByPageListReq">userInfoByPageListReq</param>
        /// <returns></returns>
        Task<IEnumerable<UserInfo>> GetUserInfoByPageList(UserInfoByPageListReq userInfoByPageListReq;

        /// <summary>
        /// 通过用户ID获取对应用户信息
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        Task<UserInfo> GetUserInfoById(string id;

        /// <summary>
        /// 添加用户信息
        /// </summary>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        Task<UserInfo> AddUserInfo(UserInfoReq userInfo;

        /// <summary>
        /// 事务添加用户信息
        /// </summary>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        Task<UserInfo> AddUserInfoTransactions(UserInfoReq userInfo;

        /// <summary>
        /// 用户信息修改
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        Task<UserInfo> UpdateUserInfo(string id, UserInfoReq userInfo;

        /// <summary>
        /// 用户信息删除
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        Task<bool> Delete(string id;
    }

创建UserOperationExampleServices类

    public class UserOperationExampleServices : IUserOperationExampleServices
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IUserRepository _userRepository;

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="unitOfWork">unitOfWork</param>
        /// <param name="userRepository">userRepository</param>
        public UserOperationExampleServices(IUnitOfWork unitOfWork, IUserRepository userRepository
        {
            _unitOfWork = unitOfWork;
            _userRepository = userRepository;
        }

        /// <summary>
        /// 获取所有用户信息
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<UserInfo>> GetAllUserInfos(
        {
            var getAllUserInfos = await _userRepository.GetAllAsync(;
            return getAllUserInfos;
        }

        /// <summary>
        /// 用户分页数据获取
        /// </summary>
        /// <param name="userInfoByPageListReq">userInfoByPageListReq</param>
        /// <returns></returns>
        public async Task<IEnumerable<UserInfo>> GetUserInfoByPageList(UserInfoByPageListReq request
        {
            //创建查询条件构造器
            FilterDefinitionBuilder<UserInfo> buildFilter = Builders<UserInfo>.Filter;
            FilterDefinition<UserInfo> filter = buildFilter.Empty;
            SortDefinition<UserInfo> sort = Builders<UserInfo>.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;
        }

        /// <summary>
        /// 通过用户ID获取对应用户信息
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        public async Task<UserInfo> GetUserInfoById(string id
        {
            var getUserInfo = await _userRepository.GetByIdAsync(id;
            return getUserInfo;
        }

        /// <summary>
        /// 添加用户信息
        /// </summary>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        public async Task<UserInfo> 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;
        }

        /// <summary>
        /// 事务添加用户信息
        /// </summary>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        public async Task<UserInfo> 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;
        }

        /// <summary>
        /// 用户信息修改
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        public async Task<UserInfo> UpdateUserInfo(string id, UserInfoReq userInfo
        {
            #region 指定字段和条件修改

            //修改条件
            var list = new List<FilterDefinition<UserInfo>>
            {
                Builders<UserInfo>.Filter.Eq("_id", new ObjectId(id
            };
            var filter = Builders<UserInfo>.Filter.And(list;

            //指定要修改的字段内容
            //参考文章:https://chsakell.gitbook.io/mongodb-csharp-docs/crud-basics/update-documents
            var updateDefinition = Builders<UserInfo>.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<FilterDefinition<UserInfo>>(;
            //list.Add(Builders<UserInfo>.Filter.Gt("CreateDate", time;//大于当前时间
            //list.Add(Builders<UserInfo>.Filter.Lt("CreateDate", time.AddDays(5;//小于当前时间+5day
            //var filter = Builders<UserInfo>.Filter.And(list;

            ////2.要修改的字段内容
            //var dic = new Dictionary<string, string>
            //{
            //    { "Status", "0" }
            //};

            ////3.批量修改
            //await _userRepository.UpdateManayAsync(dic, filter;

            #endregion

            return await _userRepository.GetByIdAsync(id;
        }

        /// <summary>
        /// 用户信息删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> Delete(string id
        {
            await _userRepository.DeleteAsync(id;
            var testUserInfo = await _userRepository.GetByIdAsync(id;
            return testUserInfo == null;
        }
    }

UserOperationExample控制创建

    /// <summary>
    /// MongoDB用户管理操作示例
    /// </summary>
    [ApiController]
    [Produces("application/json"]
    [Route("api/[controller]/[action]"]
    public class UserOperationExampleController : ControllerBase
    {
        private readonly IUserOperationExampleServices _userOperationExampleServices;

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="userOperationExampleServices">userOperationExampleServices</param>
        public UserOperationExampleController(IUserOperationExampleServices userOperationExampleServices
        {
            _userOperationExampleServices = userOperationExampleServices;
        }

        /// <summary>
        /// 获取所有用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<UserInfo>>> GetAllUserInfos(
        {
            var userInfos = await _userOperationExampleServices.GetAllUserInfos(;
            return Ok(userInfos;
        }

        /// <summary>
        /// 获取用户分页数据
        /// </summary>
        /// <param name="userInfoByPageListReq">userInfoByPageListReq</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult<IEnumerable<UserInfo>>> GetUserInfoByPageList([FromBody] UserInfoByPageListReq userInfoByPageListReq
        {
            var getUserInfoByPageList = await _userOperationExampleServices.GetUserInfoByPageList(userInfoByPageListReq;
            return Ok(getUserInfoByPageList;
        }

        /// <summary>
        /// 通过用户ID获取对应用户信息
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        [HttpGet("{id}"]
        public async Task<ActionResult<UserInfo>> GetUserInfoById(string id
        {
            var userInfo = await _userOperationExampleServices.GetUserInfoById(id;
            return Ok(userInfo;
        }

        /// <summary>
        /// 添加用户信息
        /// </summary>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult<UserInfo>> AddUserInfo([FromBody] UserInfoReq userInfo
        {
            var addUserInfo = await _userOperationExampleServices.AddUserInfo(userInfo;
            return Ok(addUserInfo;
        }

        /// <summary>
        /// 事务添加用户信息
        /// </summary>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult<UserInfo>> AddUserInfoTransactions([FromBody] UserInfoReq userInfo
        {
            //TODO:单机服务器不支持事务使用【使用MongoDB事务会报错:Standalone servers do not support transactions】,只有在集群情况下才能用
            var addUserInfo = await _userOperationExampleServices.AddUserInfoTransactions(userInfo;
            return Ok(addUserInfo;
        }

        /// <summary>
        /// 用户信息修改
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="userInfo">userInfo</param>
        /// <returns></returns>
        [HttpPut("{id}"]
        public async Task<ActionResult<UserInfo>> UpdateUserInfo(string id, [FromBody] UserInfoReq userInfo
        {
            var updateUserInfo = await _userOperationExampleServices.UpdateUserInfo(id, userInfo;
            return Ok(updateUserInfo;
        }

        /// <summary>
        /// 用户信息删除
        /// </summary>
        /// <param name="id">id</param>
        /// <returns></returns>
        [HttpDelete("{id}"]
        public async Task<ActionResult> Delete(string id
        {
            var deleteUser = await _userOperationExampleServices.Delete(id;
            return Ok(deleteUser;
        }
    }

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

//注册数据库基础操作和工作单元
builder.Services.AddScoped<IMongoContext, MongoContext>(;
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>(;
builder.Services.AddScoped<IUserRepository, UserRepository>(;

注册相关应用服务

builder.Services.AddScoped<IUserOperationExampleServices, UserOperationExampleServices>(;

Swagger用户管理操作示例展示

添加用户信息

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

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

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

获取所有用户信息

用户分页数据获取

 用户信息修改

参考文章:https://chsakell.gitbook.io/mongodb-csharp-docs/crud-basics/update-documents

用户信息删除

 

编程笔记 » .NET Core MongoDB数据仓储和工作单元模式实操

赞同 (41) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽