.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地址:GitHub - YSGStudyHards/YyFlight.ToDoList: 【.NET8 MongoDB 待办清单系统】.NET8 MongoDB从入门到实战基础教程,该项目后端使用的是.NET8、前端页面使用Blazor、使用MongoDB存储数据,更多相关内容大家可以看目录中的MongoDB从入门到实战的相关教程。该系列教程可作为.NET Core入门项目进行学习,感兴趣的小伙伴可以关注博主和我一起学习共同进步。

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{/// <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的转换。没有此特性序列化时会有如下异常提示:

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 计数器(初始化随机)

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-documentsvar 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);#endregionreturn 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.AddSingleton<IMongoConnection, MongoConnection>();
builder.Services.AddScoped<IMongoContext, MongoContext>();
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddScoped<IUserRepository, UserRepository>();

注册相关应用服务

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

Swagger用户管理操作示例展示

添加用户信息

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

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

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

获取所有用户信息

用户分页数据获取

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

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

 

 用户信息修改

指定要修改的字段内容,修改HeadPortrait、NickName、Status
参考文章:Update - MongoDB C# docs

 

 修改成功:

用户信息删除

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/263054.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kafka为什么性能这么高?

Kafka系统架构 Kafka是一个分布式流处理平台&#xff0c;具有高性能和可伸缩性的特点。它使用了一些关键的设计原则和技术&#xff0c;以实现其高性能。 上图是Kafka的架构图&#xff0c;Producer生产消息&#xff0c;以Partition的维度&#xff0c;按照一定的路由策略&#x…

Java知识点一

hello&#xff0c;大家好&#xff01;我们今天开启Java语言的学习之路&#xff0c;与C语言的学习内容有些许异同&#xff0c;今天我们来简单了解一下Java的基础知识。 一、数据类型 分两种&#xff1a;基本数据类型 引用数据类型 &#xff08;1&#xff09;整型 八种基本数…

Unity 2021.3发布WebGL设置以及nginx的配置

使用unity2021.3发布webgl 使用Unity制作好项目之后建议进行代码清理&#xff0c;这样会即将不用的命名空间去除&#xff0c;不然一会在发布的时候有些命名空间webgl会报错。 平台转换 将平台设置为webgl 设置色彩空间压缩方式 Compression Format 设置为DisabledDecompre…

【kubernetes】二进制部署k8s集群之,多master节点负载均衡以及高可用(下)

↑↑↑↑接上一篇继续部署↑↑↑↑ 之前已经完成了单master节点的部署&#xff0c;现在需要完成多master节点以及实现k8s集群的高可用 一、完成master02节点的初始化操作 二、在master01节点基础上&#xff0c;完成master02节点部署 步骤一&#xff1a;准备好master节点所需…

opengl pyqt 显示文字

目录 效果图 效果图 import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QOpenGLWidgetfrom OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import *class OpenGLWidget(QOpenGLWidget):def __init__(self, parentNone):super(OpenGLWidget…

【计算机毕业设计】541鲜花商城系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

RabbitMq:什么是RabbitMq? ①

一、RabbitMq定位 RabbitMq是一个基于消息订阅发布的一款消息中间件。 二、技术原理 核心概念 server&#xff1a;又称broker&#xff0c;接受客户端连接&#xff0c;实现AMQP实体服务。缓存代理&#xff0c;Kafka集群中的一台或多台服务器统称broker.connection&#xff1a;…

长短期记忆神经网络

目录 LSTM 神经网络架构 分类 LSTM 网络 回归 LSTM 网络 视频分类网络 更深的 LSTM 网络 网络层 分类、预测和预报 序列填充、截断和拆分 按长度对序列排序 填充序列 截断序列 拆分序列 指定填充方向 归一化序列数据 无法放入内存的数据 可视化 LSTM 层架构 …

springboot+vue项目部署配置开机自启动

1.前端部属 下载nginx解压&#xff0c;在nginx\conf下找到nginx.conf 添加如下代码 server {listen 8081;server_name localhost;charset utf-8;location / {root F:/1ceshi/dist; #前端打包路径try_files $uri $uri/ /index.html;index index.html index.htm;}l…

redis 异步队列

//produceMessage.ts 模拟生产者 import Redis from ioredis; const redis new Redis(); // 生产者&#xff1a;将消息推送到队列 async function produceMessage(queueName:string, message:string) {try {await redis.rpush(queueName, message);console.log(Produced messa…

EasyRecovery2024高级完整个人版免费下载使用

该软件的高级功能和功能选项主要包括以下几个方面&#xff1a; 恢复删除的磁盘分区&#xff1a;EasyRecovery能够快速扫描磁盘&#xff0c;寻找并恢复删除的磁盘分区&#xff0c;无需检索完整磁盘扇区。支持主流的MBR和GPT分区类型&#xff0c;实现安全可靠的分区恢复。恢复格…

Upload-Labs-Linux1【CTF】

拿到这道题目一看&#xff0c;发现是upload靶场&#xff1b;这不简简单单吗&#xff1b;结果中间还是遇到了一些小问题 小坑总结&#xff1a;该关只识别标准php语法&#xff1a;<?php phpinfo()?>格式&#xff1b;即<?php ?> 不识别<? phpinfo()?> &…

Itext生成pdf文件,html转pdf时中文一直显示不出来

之前使用freemark模板渲染ftl页面,转出的pdf中&#xff0c;css2有些样式好像不支持&#xff0c;比较常用的居中样式都没有效果&#xff0c;text-align:center 改造成使用html页面来转pdf&#xff0c;css2的样式可以生效,itext是不支持css3的弹性布局的ITextRenderer pdfRendere…

单片机51 输入和输出

一、IO口基本概念介绍 单片机的IO口&#xff08;Input/Output口&#xff09;是连接单片机与外部电路或设备的接口。单片机的IO口可以分为输入口和输出口两种&#xff0c;用于控制和监测外部设备的状态。 1. 输入口&#xff1a;单片机的输入口用于接收外部电路或设备的信号。输…

展锐S8000安卓核心板参数_紫光展锐5G核心板模块定制方案

展锐S8000核心板模块是基于八核S8000平台开发设计的&#xff0c;采用了先进的6nm EUV制程技术。搭载了全新的智能Android 13操作系统&#xff0c;展现出超强的画面解析能力和高性能双通道MIPI&#xff0c;拥有120Hz高刷新率&#xff0c;独立NPU和3.2TOPS Al算力&#xff0c;同时…

关于Kinect 互动沙盘 深度图 Shader Graph 分层

把Kinect的深度图穿给Shader Graph using com.rfilkov.kinect; using UnityEngine; using UnityEngine.UI; public class GetDepthTex : MonoBehaviour { public Material Mat_SandTable; void Update() { Mat_SandTable.SetTexture("_MainTex"…

创新性3D数据合成模型,微软推出EgoGen

随着AR、VR等设备的广泛应用,第一人称的应用开始增多。但在研发方面面临不同的挑战,例如&#xff0c;图像模糊、视觉混乱、遮挡更严重等&#xff0c;给视觉模型的训练带来重大挑战。 一方面,人工标注真实第一视角数据集&#xff0c;来培训深度学习模型的成本和难度都很高。另一…

自举升压电容

一文了解BUCK电路自举电容 - 知乎 (zhihu.com) 在BUCK电路设计中&#xff0c;一般在CB(BST)和SW管脚之间会放置一颗0.1uF的陶瓷电容Cboot&#xff0c;这颗电容被叫做自举电容&#xff1b; 有的设计中BST和SW之间串接的是一颗电阻和一颗电容&#xff0c;他们分别被叫做自举电阻…

【论文精读】OS-Copilot: Towards Generalist Computer Agents with Self-Improvement

OS-Copilot: Towards Generalist Computer Agents with Self-Improvement 前言ABSTRACT1 INTRODUCTION2 THE OS-COPILOT FRAMEWORK2.1 PLANNER2.2 CONFIGURATOR2.2.1 DECLARATIVE MEMORY2.2.2 PROCEDURAL MEMORY2.2.3 WORKING MEMORY 2.3 ACTOR 3 THE FRIDAY AGENT3.1 A RUNNIN…

C# winfroms使用socket客户端服务端代码详解

文章目录 1️⃣ 通信相关说明1.1服务端与客户端1.2 信息发送原理1.3 信息接收原理 2️⃣ socket代码2.1 客户端代码2.2 服务端代码 3️⃣ 定时任务处理报文3.1 Timers定时任务 优质资源分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_4315141…