经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MongoDB » 查看文章
.net core操作MongoDB
来源:cnblogs  作者:提伯斯  时间:2023/1/11 8:43:32  对本文有异议

前言

现实中认识的一个搞java(百万富婆)的大佬,已经转行做抖音主播了,搞技术的只能赶在年前再水一篇博客,不足之处欢迎拍砖,以免误人子弟,呔,真是太难受了
image

环境准备

  • .net core 3.1
  • MongoDB
  • Navicat Premium 16

创建项目

1.选择ASP.NET Core Web API 项目模板

image

2.配置项目信息 项目名称,项目路径

image

3.配置项目其它信息,这里选择使用.net core 3.1 不配置https

image

添加依赖

1.获取MongoDB.Driver包 版本 2.18.0

  1. 方案A. install-package MongoDB.Driver
  2. 方案B. nuget包管理工具搜索 MongoDB.Driver
  3. 方案C. 选中项目,双击,添加
  4. <ItemGroup>
  5. <PackageReference Include="MongoDB.Driver" Version="2.18.0" />
  6. </ItemGroup>

注册中间件

1.添加配置文件

  1. "MongoDB": {
  2. "ConnName": "mongodb://root:123456@127.0.0.1:27017/",
  3. "DatabaseName": "test"
  4. }

2.添加配置类

  1. public class MongoDBConfig
  2. {
  3. /// <summary>
  4. /// 连接字符串
  5. /// </summary>
  6. public string ConnName { get; set; }
  7. /// <summary>
  8. /// 数据库名称
  9. /// </summary>
  10. public string DatabaseName { get; set; }
  11. }

3.注册配置文件与中间件

  1. //读取配置文件
  2. var mongoDBOptions = Configuration.GetSection("MongoDB").Get<MongoDBConfig>();
  3. //注册配置
  4. services.Configure<MongoDBConfig>(this.Configuration.GetSection("MongoDB"));
  5. //注册中间件
  6. services.AddSingleton(new MongoClient(mongoDBOptions.ConnName));

其实就是注册了一个mongodb的客户端实例,然后用这个客户端实例来实现crud,如果你想优雅点(强迫症),也可以自定义一个拓展,来注册这个实例,这是一个通用技巧,后面使用到的类请自行注册

  1. public static class MongoDBExtensions
  2. {
  3. public static void AddMongoDB(this IServiceCollection services, Action<MongoDBConfig> setupAction)
  4. {
  5. if (setupAction == null)
  6. {
  7. throw new ArgumentNullException(nameof(setupAction));
  8. }
  9. var options = new MongoDBConfig();
  10. setupAction(options);
  11. services.Configure(setupAction);
  12. services.AddSingleton(services.AddSingleton(new MongoClient(options.ConnName)));
  13. }
  14. }

使用拓展,来注册中间件

  1. var mongoDBOptions = Configuration.GetSection("MongoDB").Get<MongoDBConfig>();
  2. services.AddMongoDB(m =>
  3. {
  4. m.ConnName = mongoDBOptions.ConnName;
  5. m.DatabaseName = mongoDBOptions.DatabaseName;
  6. });

封装基础操作

最常用的办法,就是弄个DBHelper类,这种简单粗暴的方式,在.net core里使用并不优雅(网上教程太多了,不想重复的水),这里模拟常规的仓储模式,进行演示

1.创建 Service,Repertoty,Model 文件夹
2.创建 BaseDbContext 类

  1. public class BaseDbContext
  2. {
  3. private readonly IMongoDatabase _database;
  4. public BaseDbContext(MongoClient client, IOptions<MongoDBConfig> options)
  5. {
  6. //决定使用哪个库
  7. _database = client.GetDatabase(options.Value.DatabaseName);
  8. }
  9. /// <summary>
  10. /// 数据库对象
  11. /// </summary>
  12. public IMongoDatabase MongoDatabase { get{ return _database; } }
  13. }

如果项目只操作一个数据库,直接在基类里指定操作的数据库即可,如果需要操作多个数据库,可以再新建一个子类(TestDbContext),在子类里指定要操作的数据库
前面我已经注册了mongodb的客户端跟配置文件,所以在Startup类下,可以直接注册这个类,容器会自动管理这些依赖

  1. services.AddSingleton(typeof(BaseDbContext));

如果你想更优雅点(强迫症),可以创建一个IBaseDbContext 接口,在接口里定义相关的规范

  1. services.AddSingleton<IBaseDbContext>();

3.创建 BaseRepertoty 类

  1. public class BaseRepertoty<T> where T : class, new()
  2. {
  3. private readonly IMongoDatabase _database;
  4. private readonly string _collName;
  5. public BaseRepertoty(BaseDbContext baseDbContext)
  6. {
  7. _database = baseDbContext.MongoDatabase;
  8. _collName = typeof(T).GetAttributeValue((TableAttribute m) => m.Name);
  9. _collName = _collName ?? typeof(T).Name;
  10. }
  11. }

前面我们已经注册了BaseDbContext,它的主要作用是确定操作的库,那BaseRepertoty就是对具体集合(表)的操作,这里使用泛型,避免重复的CRUD操作
我新建了一个拓展,用于获取实体类上真实集合(表)的名称,如果用户没有指定,则取实体类的类名,做为集合(表)的名称

  1. public static class AttributeExtensions
  2. {
  3. public static TValue GetAttributeValue<TAttribute, TValue>(
  4. this Type type,
  5. Func<TAttribute, TValue> valueSelector)
  6. where TAttribute : Attribute
  7. {
  8. var att = type.GetCustomAttributes(
  9. typeof(TAttribute), true
  10. ).FirstOrDefault() as TAttribute;
  11. if (att != null)
  12. {
  13. return valueSelector(att);
  14. }
  15. return default(TValue);
  16. }
  17. }

4.创建 UserInfoRepertoty 类

  1. public class UserInfoRepertoty : BaseRepertoty<UserInfo>
  2. {
  3. public UserInfoRepertoty(BaseDbContext baseDbContext) : base(baseDbContext)
  4. {
  5. }
  6. }

它的作用是指定操作具体的集合(表),这个类是非必须的,它只是指定了泛型的具体类型,也可以在server层调用的时候指定

5.创建 UserInfo 实体类

  1. [Table("UserInfo")]
  2. public class UserInfo
  3. {
  4. /// <summary>
  5. /// 主键
  6. /// </summary>
  7. [BsonId]
  8. public ObjectId Id { get; set; }
  9. /// <summary>
  10. /// 用户名
  11. /// </summary>
  12. public string Name { get; set; }
  13. /// <summary>
  14. /// 年龄
  15. /// </summary>
  16. public int Age { get; set; }
  17. /// <summary>
  18. /// 创建时间
  19. /// </summary>
  20. [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
  21. public DateTime CreateTime { get; set; }
  22. /// <summary>
  23. /// 合作伙伴
  24. /// </summary>
  25. public List<Partner> PartnerList { get; set; }
  26. /// <summary>
  27. /// 其它信息
  28. /// </summary>
  29. public Info Info { get; set; }
  30. }
  31. public class Partner
  32. {
  33. /// <summary>
  34. /// 伙伴名称
  35. /// </summary>
  36. public string Name { get; set; }
  37. /// <summary>
  38. /// 合作状态
  39. /// </summary>
  40. public int? Status { get; set; }
  41. }
  42. public class Info
  43. {
  44. /// <summary>
  45. /// 身份编码
  46. /// </summary>
  47. public string Code { get; set; }
  48. /// <summary>
  49. /// 图片
  50. /// </summary>
  51. public string Pic { get; set; }
  52. }

mongodb里默认的主键是_id,它会自动生成,类型为ObjectId,强烈推荐使用自动生成,速度快,且能提供获取对应的时间戳的方法

  1. ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
  2. 4个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
  3. 接下来的3个字节是机器标识码
  4. 紧接的两个字节由进程 id 组成 PID
  5. 最后三个字节是随机数

时间类型要做对应的处理,标记为当前时间

其它常用注解说明

  1. BsonId修饰的字段对应BsonDocument中的_id;
  2. BsonDefaultValue(value)用于指定默认值;
  3. BsonIgnore表示不映射,即使BsonDocument中包含该字段也不会赋值给属性;
  4. BsonExtraElements修饰的字段用于存储没有映射到类中的其他属性;
  5. BsonElement可以指定修饰的属性映射到BsonDocument中的哪个字段;

使用mongodb的一个主要原因,就是它灵活的存储方式,类json,我们就来体验一番,基于这个模型来进行CRUD,我定义的类型如下,基本上能覆盖99%的使用场景

ObjectId (主键)
string (字符串)
int (数字)
object (对象)
array (数组)

我们在BaseRepertoty类里,实现CRUD,完整代码如下

  1. public class BaseRepertoty<T> where T : class, new()
  2. {
  3. private readonly IMongoDatabase _database;
  4. private readonly string _collName;
  5. public BaseRepertoty(BaseDbContext baseDbContext)
  6. {
  7. _database = baseDbContext.MongoDatabase;
  8. _collName = typeof(T).GetAttributeValue((TableAttribute m) => m.Name);
  9. _collName = _collName ?? typeof(T).Name;
  10. }
  11. #region Add 添加一条数据
  12. /// <summary>
  13. /// 添加一条数据
  14. /// </summary>
  15. /// <param name="t">添加的实体</param>
  16. /// <returns></returns>
  17. public bool Add(T t)
  18. {
  19. try
  20. {
  21. var client = _database.GetCollection<T>(_collName);
  22. client.InsertOne(t);
  23. return true;
  24. }
  25. catch (Exception ex)
  26. {
  27. return false;
  28. }
  29. }
  30. #endregion
  31. #region AddAsync 异步添加一条数据
  32. /// <summary>
  33. /// 异步添加一条数据
  34. /// </summary>
  35. /// <param name="t">添加的实体</param>
  36. /// <returns></returns>
  37. public async Task<bool> AddAsync(T t)
  38. {
  39. try
  40. {
  41. var client = _database.GetCollection<T>(_collName);
  42. await client.InsertOneAsync(t);
  43. return true;
  44. }
  45. catch
  46. {
  47. return false;
  48. }
  49. }
  50. #endregion
  51. #region InsertMany 批量插入
  52. /// <summary>
  53. /// 批量插入
  54. /// </summary>
  55. /// <param name="t">实体集合</param>
  56. /// <returns></returns>
  57. public bool InsertMany(List<T> t)
  58. {
  59. try
  60. {
  61. var client = _database.GetCollection<T>(_collName);
  62. client.InsertMany(t);
  63. return true;
  64. }
  65. catch (Exception ex)
  66. {
  67. return false;
  68. }
  69. }
  70. #endregion
  71. #region InsertManyAsync 异步批量插入
  72. /// <summary>
  73. /// 异步批量插入
  74. /// </summary>
  75. /// <param name="t">实体集合</param>
  76. /// <returns></returns>
  77. public async Task<bool> InsertManyAsync(List<T> t)
  78. {
  79. try
  80. {
  81. var client = _database.GetCollection<T>(_collName);
  82. await client.InsertManyAsync(t);
  83. return true;
  84. }
  85. catch
  86. {
  87. return false;
  88. }
  89. }
  90. #endregion
  91. #region UpdateOne 修改数据(单条)
  92. /// <summary>
  93. /// 批量修改数据
  94. /// </summary>
  95. /// <param name="update">要修改的字段</param>
  96. /// <param name="filter">修改条件</param>
  97. /// <returns></returns>
  98. public UpdateResult UpdateOne(UpdateDefinition<T> update, FilterDefinition<T> filter)
  99. {
  100. try
  101. {
  102. var client = _database.GetCollection<T>(_collName);
  103. return client.UpdateOne(filter, update);
  104. }
  105. catch (Exception ex)
  106. {
  107. throw ex;
  108. }
  109. }
  110. #endregion
  111. #region UpdateOneAsync 异步批量修改数据
  112. /// <summary>
  113. /// 异步批量修改数据
  114. /// </summary>
  115. /// <param name="update">要修改的字段</param>
  116. /// <param name="filter">修改条件</param>
  117. /// <returns></returns>
  118. public async Task<UpdateResult> UpdateOneAsync(UpdateDefinition<T> update, FilterDefinition<T> filter)
  119. {
  120. try
  121. {
  122. var client = _database.GetCollection<T>(_collName);
  123. return await client.UpdateOneAsync(filter, update);
  124. }
  125. catch (Exception ex)
  126. {
  127. throw ex;
  128. }
  129. }
  130. #endregion
  131. #region UpdateManay 批量修改数据
  132. /// <summary>
  133. /// 批量修改数据
  134. /// </summary>
  135. /// <param name="update">要修改的字段</param>
  136. /// <param name="filter">修改条件</param>
  137. /// <returns></returns>
  138. public UpdateResult UpdateManay(UpdateDefinition<T> update, FilterDefinition<T> filter)
  139. {
  140. try
  141. {
  142. var client = _database.GetCollection<T>(_collName);
  143. return client.UpdateMany(filter, update);
  144. }
  145. catch (Exception ex)
  146. {
  147. throw ex;
  148. }
  149. }
  150. #endregion
  151. #region UpdateManayAsync 异步批量修改数据
  152. /// <summary>
  153. /// 异步批量修改数据
  154. /// </summary>
  155. /// <param name="update">要修改的字段</param>
  156. /// <param name="filter">修改条件</param>
  157. /// <returns></returns>
  158. public async Task<UpdateResult> UpdateManayAsync(UpdateDefinition<T> update, FilterDefinition<T> filter)
  159. {
  160. try
  161. {
  162. var client = _database.GetCollection<T>(_collName);
  163. return await client.UpdateManyAsync(filter, update);
  164. }
  165. catch (Exception ex)
  166. {
  167. throw ex;
  168. }
  169. }
  170. #endregion
  171. #region DeleteOne 删除一条数据
  172. /// <summary>
  173. /// 删除多条数据
  174. /// </summary>
  175. /// <param name="filter">删除的条件</param>
  176. /// <returns></returns>
  177. public DeleteResult DeleteOne(FilterDefinition<T> filter)
  178. {
  179. try
  180. {
  181. var client = _database.GetCollection<T>(_collName);
  182. return client.DeleteOne(filter);
  183. }
  184. catch (Exception ex)
  185. {
  186. throw ex;
  187. }
  188. }
  189. #endregion
  190. #region DeleteOneAsync 异步删除一条数据
  191. /// <summary>
  192. /// 异步删除多条数据
  193. /// </summary>
  194. /// <param name="filter">删除的条件</param>
  195. /// <returns></returns>
  196. public async Task<DeleteResult> DeleteOneAsync(FilterDefinition<T> filter)
  197. {
  198. try
  199. {
  200. var client = _database.GetCollection<T>(_collName);
  201. return await client.DeleteOneAsync(filter);
  202. }
  203. catch (Exception ex)
  204. {
  205. throw ex;
  206. }
  207. }
  208. #endregion
  209. #region DeleteMany 删除多条数据
  210. /// <summary>
  211. /// 删除多条数据
  212. /// </summary>
  213. /// <param name="filter">删除的条件</param>
  214. /// <returns></returns>
  215. public DeleteResult DeleteMany(FilterDefinition<T> filter)
  216. {
  217. try
  218. {
  219. var client = _database.GetCollection<T>(_collName);
  220. return client.DeleteMany(filter);
  221. }
  222. catch (Exception ex)
  223. {
  224. throw ex;
  225. }
  226. }
  227. #endregion
  228. #region DeleteManyAsync 异步删除多条数据
  229. /// <summary>
  230. /// 异步删除多条数据
  231. /// </summary>
  232. /// <param name="filter">删除的条件</param>
  233. /// <returns></returns>
  234. public async Task<DeleteResult> DeleteManyAsync(FilterDefinition<T> filter)
  235. {
  236. try
  237. {
  238. var client = _database.GetCollection<T>(_collName);
  239. return await client.DeleteManyAsync(filter);
  240. }
  241. catch (Exception ex)
  242. {
  243. throw ex;
  244. }
  245. }
  246. #endregion
  247. #region FindOne 根据id查询一条数据
  248. /// <summary>
  249. /// 根据id查询一条数据
  250. /// </summary>
  251. /// <param name="id">objectid</param>
  252. /// <param name="field">要查询的字段,不写时查询全部</param>
  253. /// <returns></returns>
  254. public T FindOne(string id, bool isObjectId = true, string[] field = null)
  255. {
  256. try
  257. {
  258. var client = _database.GetCollection<T>(_collName);
  259. FilterDefinition<T> filter;
  260. if (isObjectId)
  261. {
  262. filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
  263. }
  264. else
  265. {
  266. filter = Builders<T>.Filter.Eq("_id", id);
  267. }
  268. //不指定查询字段
  269. if (field == null || field.Length == 0)
  270. {
  271. return client.Find(filter).FirstOrDefault<T>();
  272. }
  273. //制定查询字段
  274. var fieldList = new List<ProjectionDefinition<T>>();
  275. for (int i = 0; i < field.Length; i++)
  276. {
  277. fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
  278. }
  279. var projection = Builders<T>.Projection.Combine(fieldList);
  280. fieldList?.Clear();
  281. return client.Find(filter).Project<T>(projection).FirstOrDefault<T>();
  282. }
  283. catch (Exception ex)
  284. {
  285. throw ex;
  286. }
  287. }
  288. #endregion
  289. #region FindOneAsync 异步根据id查询一条数据
  290. /// <summary>
  291. /// 异步根据id查询一条数据
  292. /// </summary>
  293. /// <param name="id">objectid</param>
  294. /// <returns></returns>
  295. public async Task<T> FindOneAsync(string id, bool isObjectId = true, string[] field = null)
  296. {
  297. try
  298. {
  299. var client = _database.GetCollection<T>(_collName);
  300. FilterDefinition<T> filter;
  301. if (isObjectId)
  302. {
  303. filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
  304. }
  305. else
  306. {
  307. filter = Builders<T>.Filter.Eq("_id", id);
  308. }
  309. //不指定查询字段
  310. if (field == null || field.Length == 0)
  311. {
  312. return await client.Find(filter).FirstOrDefaultAsync();
  313. }
  314. //制定查询字段
  315. var fieldList = new List<ProjectionDefinition<T>>();
  316. for (int i = 0; i < field.Length; i++)
  317. {
  318. fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
  319. }
  320. var projection = Builders<T>.Projection.Combine(fieldList);
  321. fieldList?.Clear();
  322. return await client.Find(filter).Project<T>(projection).FirstOrDefaultAsync();
  323. }
  324. catch (Exception ex)
  325. {
  326. throw ex;
  327. }
  328. }
  329. #endregion
  330. #region FindList 查询集合
  331. /// <summary>
  332. /// 查询集合
  333. /// </summary>
  334. /// <param name="filter">查询条件</param>
  335. /// <param name="field">要查询的字段,不写时查询全部</param>
  336. /// <param name="sort">要排序的字段</param>
  337. /// <returns></returns>
  338. public List<T> FindList(FilterDefinition<T> filter, string[] field = null, SortDefinition<T> sort = null)
  339. {
  340. try
  341. {
  342. var client = _database.GetCollection<T>(_collName);
  343. //不指定查询字段
  344. if (field == null || field.Length == 0)
  345. {
  346. if (sort == null) return client.Find(filter).ToList();
  347. //进行排序
  348. return client.Find(filter).Sort(sort).ToList();
  349. }
  350. //制定查询字段
  351. var fieldList = new List<ProjectionDefinition<T>>();
  352. for (int i = 0; i < field.Length; i++)
  353. {
  354. fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
  355. }
  356. var projection = Builders<T>.Projection.Combine(fieldList);
  357. fieldList?.Clear();
  358. if (sort == null) return client.Find(filter).Project<T>(projection).ToList();
  359. //排序查询
  360. return client.Find(filter).Sort(sort).Project<T>(projection).ToList();
  361. }
  362. catch (Exception ex)
  363. {
  364. throw ex;
  365. }
  366. }
  367. #endregion
  368. #region FindListAsync 异步查询集合
  369. /// <summary>
  370. /// 异步查询集合
  371. /// </summary>
  372. /// <param name="filter">查询条件</param>
  373. /// <param name="field">要查询的字段,不写时查询全部</param>
  374. /// <param name="sort">要排序的字段</param>
  375. /// <returns></returns>
  376. public async Task<List<T>> FindListAsync(FilterDefinition<T> filter, string[] field = null, SortDefinition<T> sort = null)
  377. {
  378. try
  379. {
  380. var client = _database.GetCollection<T>(_collName);
  381. //不指定查询字段
  382. if (field == null || field.Length == 0)
  383. {
  384. //return await client.Find(new BsonDocument()).ToListAsync();
  385. if (sort == null) return await client.Find(filter).ToListAsync();
  386. return await client.Find(filter).Sort(sort).ToListAsync();
  387. }
  388. //制定查询字段
  389. var fieldList = new List<ProjectionDefinition<T>>();
  390. for (int i = 0; i < field.Length; i++)
  391. {
  392. fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
  393. }
  394. var projection = Builders<T>.Projection.Combine(fieldList);
  395. fieldList?.Clear();
  396. if (sort == null) return await client.Find(filter).Project<T>(projection).ToListAsync();
  397. //排序查询
  398. return await client.Find(filter).Sort(sort).Project<T>(projection).ToListAsync();
  399. }
  400. catch (Exception ex)
  401. {
  402. throw ex;
  403. }
  404. }
  405. #endregion
  406. #region FindListByPage 分页查询集合
  407. /// <summary>
  408. /// 分页查询集合
  409. /// </summary>
  410. /// <param name="filter">查询条件</param>
  411. /// <param name="pageIndex">当前页</param>
  412. /// <param name="pageSize">页容量</param>
  413. /// <param name="count">总条数</param>
  414. /// <param name="field">要查询的字段,不写时查询全部</param>
  415. /// <param name="sort">要排序的字段</param>
  416. /// <returns></returns>
  417. public List<T> FindListByPage(FilterDefinition<T> filter, int pageIndex, int pageSize, out long count, string[] field = null, SortDefinition<T> sort = null)
  418. {
  419. try
  420. {
  421. var client = _database.GetCollection<T>(_collName);
  422. count = client.CountDocuments(filter);
  423. //不指定查询字段
  424. if (field == null || field.Length == 0)
  425. {
  426. if (sort == null) return client.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
  427. //进行排序
  428. return client.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
  429. }
  430. //制定查询字段
  431. var fieldList = new List<ProjectionDefinition<T>>();
  432. for (int i = 0; i < field.Length; i++)
  433. {
  434. fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
  435. }
  436. var projection = Builders<T>.Projection.Combine(fieldList);
  437. fieldList?.Clear();
  438. //不排序
  439. if (sort == null) return client.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
  440. //排序查询
  441. return client.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
  442. }
  443. catch (Exception ex)
  444. {
  445. throw ex;
  446. }
  447. }
  448. #endregion
  449. #region FindListByPageAsync 异步分页查询集合
  450. /// <summary>
  451. /// 异步分页查询集合
  452. /// </summary>
  453. /// <param name="filter">查询条件</param>
  454. /// <param name="pageIndex">当前页</param>
  455. /// <param name="pageSize">页容量</param>
  456. /// <param name="field">要查询的字段,不写时查询全部</param>
  457. /// <param name="sort">要排序的字段</param>
  458. /// <returns></returns>
  459. public async Task<List<T>> FindListByPageAsync(FilterDefinition<T> filter, int pageIndex, int pageSize, string[] field = null, SortDefinition<T> sort = null)
  460. {
  461. try
  462. {
  463. var client = _database.GetCollection<T>(_collName);
  464. //不指定查询字段
  465. if (field == null || field.Length == 0)
  466. {
  467. if (sort == null) return await client.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
  468. //进行排序
  469. return await client.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
  470. }
  471. //制定查询字段
  472. var fieldList = new List<ProjectionDefinition<T>>();
  473. for (int i = 0; i < field.Length; i++)
  474. {
  475. fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
  476. }
  477. var projection = Builders<T>.Projection.Combine(fieldList);
  478. fieldList?.Clear();
  479. //不排序
  480. if (sort == null) return await client.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
  481. //排序查询
  482. return await client.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
  483. }
  484. catch (Exception ex)
  485. {
  486. throw ex;
  487. }
  488. }
  489. #endregion
  490. #region Count 根据条件获取总数
  491. /// <summary>
  492. /// 根据条件获取总数
  493. /// </summary>
  494. /// <param name="filter">条件</param>
  495. /// <returns></returns>
  496. public long Count(FilterDefinition<T> filter)
  497. {
  498. try
  499. {
  500. var client = _database.GetCollection<T>(_collName);
  501. return client.CountDocuments(filter);
  502. }
  503. catch (Exception ex)
  504. {
  505. throw ex;
  506. }
  507. }
  508. #endregion
  509. #region CountAsync 异步根据条件获取总数
  510. /// <summary>
  511. /// 异步根据条件获取总数
  512. /// </summary>
  513. /// <param name="filter">条件</param>
  514. /// <returns></returns>
  515. public async Task<long> CountAsync(FilterDefinition<T> filter)
  516. {
  517. try
  518. {
  519. var client = _database.GetCollection<T>(_collName);
  520. return await client.CountDocumentsAsync(filter);
  521. }
  522. catch (Exception ex)
  523. {
  524. throw ex;
  525. }
  526. }
  527. #endregion
  528. }

6.创建 UserInfoService 类

  1. public class UserInfoService
  2. {
  3. private readonly UserInfoRepertoty _userInfoRepertoty;
  4. private readonly FilterDefinitionBuilder<UserInfo> _buildFilter;
  5. public UserInfoService(UserInfoRepertoty userInfoRepertoty)
  6. {
  7. _userInfoRepertoty = userInfoRepertoty;
  8. _buildFilter = Builders<UserInfo>.Filter;
  9. }
  10. }

体验mongodb独特的使用方式,这里挑出两个具有代表性的操作进行讲解,测试数据
image

分页查询集合(表)

  • 1.动态条件查询
  • 2.查询文档指定字段
  • 3.排序
  • 4.分页

定义查询操作

  1. FilterDefinition<UserInfo> filter = _buildFilter.Empty;

查询条件由查询条件构造器构建,这个地方网上很多示例写的有bug,当查询所有集合(表)数据的时候,filter = null 在转换的时候会抛出异常

  1. //创建查询条件构造器
  2. FilterDefinitionBuilder<UserInfo> _buildFilter = Builders<UserInfo>.Filter;
  3. //定义查询条件
  4. FilterDefinition<UserInfo> filter = null;
  5. if(!string.IsNullOrEmpty(request.Name)) filter = _buildFilter.Eq(m => m.Name, request.Name);

这里有很多种类型的构造器,对应不同的操作

  1. //排序操作
  2. SortDefinition<UserInfo> sort
  3. //排序构造器
  4. Builders<UserInfo>.Sort
  5. 修改操作
  6. UpdateDefinition<UserInfo> update
  7. //修改构造器
  8. Builders<UserInfo>.Update

完整的查询示例,比较麻烦的地方,是针对数组的条件查询,如果嵌套的层数比较多,查询也是同理的套娃查询

  1. public class GetUserListRequest
  2. {
  3. /// <summary>
  4. /// 名称
  5. /// </summary>
  6. public string Name { get; set; }
  7. /// <summary>
  8. /// 年龄
  9. /// </summary>
  10. public int? Age { get; set; }
  11. /// <summary>
  12. /// 创建时间
  13. /// </summary>
  14. public DateTime CreateTime { get; set; }
  15. /// <summary>
  16. /// 合作伙伴
  17. /// </summary>
  18. public Partner PartnerList { get; set; }
  19. /// <summary>
  20. /// 信息
  21. /// </summary>
  22. public Info Info { get; set; }
  23. }
  24. public async Task<List<UserInfo>> GetUserPageList(GetUserListRequest request)
  25. {
  26. if (request == null) return new List<UserInfo>();
  27. FilterDefinition<UserInfo> filter = _buildFilter.Empty;
  28. SortDefinition<UserInfo> sort = Builders<UserInfo>.Sort.Ascending(m => m.Age);
  29. if (!string.IsNullOrEmpty(request.Name))
  30. {
  31. filter = _buildFilter.Eq(m => m.Name, request.Name);
  32. }
  33. if (request.Age.HasValue)
  34. {
  35. filter = _buildFilter.Eq(m => m.Age, request.Age);
  36. }
  37. if (request.PartnerList != null)
  38. {
  39. if (request.PartnerList.Status.HasValue)
  40. {
  41. filter = _buildFilter.ElemMatch("PartnerList", Builders<Partner>.Filter.Eq(m => m.Status, request.PartnerList.Status));
  42. }
  43. }
  44. if (request.Info != null)
  45. {
  46. if (!string.IsNullOrEmpty(request.Info.Code))
  47. {
  48. filter = _buildFilter.Eq(m => m.Info.Code, request.Info.Code);
  49. }
  50. }
  51. var list = await _userInfoRepertoty.FindListByPageAsync(filter,1,3, new string[] { "Name","Age", "CreateTime" }, sort);
  52. return list;
  53. }

动态条件查询(查询全部)

  1. var list = await _userInfoRepertoty.FindListByPageAsync(filter, 1, 30);

image

条件查询,排序,分页,查询指定字段

  1. var list = await _userInfoRepertoty.FindListByPageAsync(filter,1,3, new string[] { "Name","Age", "CreateTime" }, sort);

image
除了使用对象模型进行操作,也可以直接使用mongodb原生的BsonDocument进行操作

  1. var buildFilter = Builders<BsonDocument>.Filter;
  2. FilterDefinition<BsonDocument> filter = _buildFilter.Empty;;
  3. BsonDocument bson = new BsonDocument
  4. {
  5. { "Age",20},
  6. {"Info.Status",3 }
  7. };
  8. foreach (var bs in bson)
  9. {
  10. filter = _buildFilter.Eq(bs.Name, bs.Value);
  11. }
  12. var sort = Builders<BsonDocument>.Sort;
  13. var list = await collection.Find(filter).Sort(sort.Descending("age")).ToListAsync();

修改集合(表)的数据

  • 1.修改满足条件的文档
  • 2.修改文档的部分字段
  1. public async Task UpdateUserInfo()
  2. {
  3. //修改条件
  4. FilterDefinition<UserInfo> filter = _buildFilter.Empty;
  5. filter = _buildFilter.Eq(m => m.Name, "tibos");
  6. filter = _buildFilter.ElemMatch(list => list.PartnerList, child => child.Status == 1);
  7. //修改字段
  8. var update = Builders<UserInfo>.Update.Set("Age",100).Set("PartnerList.$.Name", "ppp").Set("PartnerList.$.Status", "");
  9. await _userInfoRepertoty.UpdateManayAsync(update, filter);
  10. }

原文链接:https://www.cnblogs.com/tibos/p/17033046.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号