MongoDB 系列(一) C# 简易入门封装

时间:2023-03-09 19:13:08
MongoDB 系列(一) C# 简易入门封装

之前写过一篇关于MongoDB的封装 发现太过繁琐 于是打算从新写一篇简易版

1:关于MongoDB的安装请自行百度,进行权限认证的时候有一个小坑,3.0之后授权认证方式默认的SCRAM-SHA-1模式,

需要首先命令创建一个用户,然后Drop掉这个用户,然后修改system.version里的authScheam为3,在没有创建用户的情况下

authScheam的值貌似是查询不到的。

MongoDB 系列(一) C# 简易入门封装

修改成3后,授权验证方式就变成了MONGODB-CR

 2:建立一个聚合根和实体

 public interface ICore
{
string Id { set; get; }
} /// <summary>
/// 聚合根
/// </summary>
public interface IAggregateRoot
{
string Id { set; get; }
} /// <summary>
/// 实体
/// </summary>
public abstract class Core : ICore
{
public string Id { set; get; } = Guid.NewGuid().ToString();
}

3:建立实体

/// <summary>
/// 用户
/// </summary>
public class User : Core, IAggregateRoot
{
/// <summary>
/// 名字
/// </summary>
public string Name { set; get; } /// <summary>
/// 身份证
/// </summary>
public string Cardcertificate { set; get; } /// <summary>
/// 性别
/// </summary>
public Gender Gender { set; get; } = Gender.Boy; /// <summary>
/// 用户的房屋信息
/// </summary>
public List<House> Houses { set; get; } = new List<House>();
} public class House : Core
{
public string Adress { set; get; }
} public enum Gender
{
Boy = ,
Gril =
}

4:建立一个接口Context似于EF的DBContext

    public interface IMongoDBContext
{ /// <summary>
/// 具体的表连接器
/// </summary>
/// <typeparam name="K"></typeparam>
/// <returns></returns>
IMongoCollection<K> DbSet<K>() where K : IAggregateRoot; }

添加一个接口的实现

MongoDB 系列(一) C# 简易入门封装

Client 表示的是Mongodb客户端驱动链接 类似于ADO里的SqlConnection

DataBase 表示的是具体的数据库

DbSet 指定具体的表

MongoCredential 认证授权的加密方式

3:建立一个具体的DBContext

MongoDB 系列(一) C# 简易入门封装

BasicContext  类似于EF里面大家直接链接具体库的DBContext

Users User表的映射

4:建立一个MongoDB访问的扩展类

    public static class MongodbExpansion
{
/// <summary>
/// 单个对象添加
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="entity"></param>
public static void Add<T>(this IMongoCollection<T> collection, T entity) where T : IAggregateRoot
=> collection.InsertOne(entity); /// <summary>
/// 集合添加
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="entitys"></param>
public static void AddRange<T>(this IMongoCollection<T> collection, List<T> entitys) where T : IAggregateRoot
=> collection.InsertMany(entitys); /// <summary>
/// entity mongodb需要更新的实体 properts需要更新的集合属性,大小写不限 默认更新整个对象 replace 默认空属性不修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="entity">mongodb需要更新的实体</param>
/// <param name="properts">需要更新的集合属性,大小写不限 默认更新整个对象 </param>
/// <param name="replace">默认对象属性为空时不替换当前值</param>
public static void Update<T>(this IMongoCollection<T> collection, T entity, List<string> properts = null, bool replace = false) where T : IAggregateRoot
{
if (entity == null)
throw new NullReferenceException(); var type = entity.GetType();
///修改的属性集合
var list = new List<UpdateDefinition<T>>(); foreach (var propert in type.GetProperties())
{
if (propert.Name.ToLower() != "id")
{
if (properts == null || properts.Count < || properts.Any(o => o.ToLower() == propert.Name.ToLower()))
{
var replaceValue = propert.GetValue(entity);
if (replaceValue != null)
{
list.Add(Builders<T>.Update.Set(propert.Name, replaceValue));
}
else if (replace)
list.Add(Builders<T>.Update.Set(propert.Name, replaceValue));
}
}
}
#region 有可修改的属性
if (list.Count > )
{
///合并多个修改//new List<UpdateDefinition<T>>() { Builders<T>.Update.Set("Name", "111") }
var builders = Builders<T>.Update.Combine(list);
///执行提交修改
collection.UpdateOne(o => o.Id == entity.Id, builders);
}
#endregion } /// <summary>
/// 移除根据ID
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="entity"></param>
public static void Remove<T>(this IMongoCollection<T> collection, T entity) where T : IAggregateRoot
=> collection.DeleteOne(o => o.Id == entity.Id); /// <summary>
/// 移除表达式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="expression"></param>
public static void Remove<T>(this IMongoCollection<T> collection, Expression<Func<T, bool>> expression) where T : IAggregateRoot
=> collection.DeleteOne(expression); public static IFindFluent<T, T> Where<T>(this IMongoCollection<T> collection, Expression<Func<T, bool>> expression)
=> expression == null ? collection.Find(Builders<T>.Filter.Empty) : collection.Find(expression); /// <summary>
/// MongoDB里面是没有实现IQueryable的 所以想要使用习惯的SELECT我们只能自己封装一下
/// </summary>
/// <typeparam name="TDocument"></typeparam>
/// <typeparam name="TProjection"></typeparam>
/// <typeparam name="TNewProjection">返回新的数据类型</typeparam>
/// <param name="IQueryable"></param>
/// <param name="projection"></param>
/// <returns></returns>
public static IFindFluent<TDocument, TNewProjection> Select<TDocument, TProjection, TNewProjection>(this IFindFluent<TDocument, TProjection> IQueryable, Expression<Func<TDocument, TNewProjection>> projection)
=> IQueryable.Project(projection); /// <summary>
/// 获得筛选后的首个元素
/// </summary>
/// <typeparam name="TDocument"></typeparam>
/// <typeparam name="T"></typeparam>
/// <param name="IQueryable"></param>
/// <returns></returns>
public static T FirstOrDefault<TDocument, T>(this IFindFluent<TDocument, T> IQueryable)
=> IQueryable.First(); /// <summary>
/// 直接支持表达式树后的首个满足对象
/// </summary>
/// <typeparam name="TDocument"></typeparam>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="expression"></param>
/// <returns></returns>
public static T FirstOrDefault<TDocument, T>(this IMongoCollection<T> collection, Expression<Func<T, bool>> expression = null)
=> expression == null ? collection.Find(Builders<T>.Filter.Empty).First() : collection.Find(expression).First();
}
Builders<T>.Update.Combine 方法是将多个UpdateDefinition<T>修改设置合并成一个builder对象执行

IFindFluent 所返回的都是MongoDB执行的命令

MongoDB客户端驱动也是支持异步操作的我这里就没有写了 有兴趣的可以自己研究下

5:建立测试仓储

MongoDB 系列(一) C# 简易入门封装

6:仓储的实现  是不是看起来有点EF的感觉? ~0~

MongoDB 系列(一) C# 简易入门封装

MongoDB 系列(一) C# 简易入门封装

7:建立Service接口

MongoDB 系列(一) C# 简易入门封装

8 领域服务的实现

MongoDB 系列(一) C# 简易入门封装

9:单元测试用例

MongoDB 系列(一) C# 简易入门封装

MongoDB 系列(一) C# 简易入门封装

 BasicContext Context = new BasicContext();
Context.Users.Add(new Entity.User()
{
Name = "小七子",
Cardcertificate = "",
Gender = Entity.Gender.Boy,
Houses = new System.Collections.Generic.List<Entity.House>() { new Entity.House() { Adress = "中关村110号双拼别墅" } }
}); Context.Users.Where(o => o.Cardcertificate == "").ToList(); Context.Users.Update(new Entity.User() { }); Context.Users.Remove(new Entity.User() { }); Context.Users.Where().Select(o => o.Name).ToList();
Console.ReadKey();