(三)Mongdb在.net中的运用
1:在项目中引入 MongoDB.Bson.dll,MongoDB.Driver.dll,MongoDB.Driver.Core.dll
(一)基础方法
2.链接配置
private const string MongoDBConnectionStr = "mongodb://dbowneruser:123456@localhost:27019?authSource=test;connectTimeout=600000;maxWaitTime=600000;serverSelectionTimeout=600000";
3.客户端链接配置
private static MongoClient client;
private static IMongoDatabase database;
//数据库名称
private static string DefaultDataBaseName = "test";
public MongoDBHelper()
{
GetConnection(DefaultDataBaseName);
}
private void GetConnection(string dataBaseName)
{
client = new MongoClient(MongoDBConnectionStr);
database = client.GetDatabase(dataBaseName);
}
4.插入单条数据
public string Insert<T>(string collectionName, T obj)
{
try
{
if (database == null)
{
return "没有指定数据库";
}
var collection = database.GetCollection<T>(collectionName);
collection.InsertOne(obj);
return "ok";
}
catch (Exception e)
{
return e.Message;
}
}
5.插入多条数据
public string Inserts<T>(string collectionName, IEnumerable<T> objs)
{
try
{
if (database == null)
{
return "没有指定数据库";
}
if (objs == null)
{
return "对象不能为空";
}
var collection = database.GetCollection<T>(collectionName);
collection.InsertMany(objs);
return "ok";
}
catch (Exception e)
{
return e.Message;
}
}
6.根据条件查询数据
public IFindFluent<T, T> Find<T>(string collectionName, FilterDefinition<T> filter = null, FindOptions options = null)
{
if (database == null)
{
return null;
}
var collection = database.GetCollection<T>(collectionName);
return collection.Find(filter, options);
}
7.删除一条数据
public string DeleteOne<T>(string collectionName, FilterDefinition<T> filter)
{
try
{
if (database == null)
{
return null;
}
var collection = database.GetCollection<T>(collectionName);
collection.DeleteOne(filter);
return "ok";
}
catch (Exception e)
{
return e.Message;
}
}
8.删除多条数据
public string DeleteMany<T>(string collectionName, Expression<Func<T, bool>> filter1)
{
try
{
if (database == null)
{
return null;
}
var collection = database.GetCollection<T>(collectionName);
collection.DeleteMany(filter1);
return "ok";
}
catch (Exception e)
{
return e.Message;
}
}
9.一次修改一条数据
public string UpdateOne<T>(string collectionName, FilterDefinition<T> filter, UpdateDefinition<T> update)
{
try
{
var collection = database.GetCollection<T>(collectionName);
collection.UpdateOne(filter, update);
return "ok";
}
catch (Exception e)
{
return e.Message;
}
}
10一次修改多条数据
public string UpdateMany<T>(string collectionName, FilterDefinition<T> filter, UpdateDefinition<T> update)
{
try
{
var collection = database.GetCollection<T>(collectionName);
collection.UpdateMany(filter, update);
return "ok";
}
catch (Exception e)
{
return e.Message;
}
}
11分页查询
public List<T> GetProductSkip<T>(string collectionName, FilterDefinition<T> filter, SortDefinition<T> sort = null, string[] field = null)
{
var collection = database.GetCollection<T>(collectionName);
//查询所有字段的时候
if (field.Length == 0 || field == null)
{
if (sort == null)
{
//不排序
return collection.Find(filter).Skip((0) * 15).Limit(15).ToList();
}
else
{
//排序
return collection.Find(filter).Sort(sort).Skip((0) * 15).Limit(15).ToList();
}
}
else
{
//查询指定字段的时候
var fieldList = new List<ProjectionDefinition<T>>();
for (int i = 0; i < field.Length; i++)
{
fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
}
var projection = Builders<T>.Projection.Combine(fieldList);
fieldList?.Clear();
if (sort == null)
{
//不排序
return collection.Find(filter).Project<T>(projection).Skip((0) * 15).Limit(15).ToList();
}
else
{
//排序
return collection.Find(filter).Sort(sort).Project<T>(projection).Skip((0) * 15).Limit(15).ToList();
}
}
}
(二)业务方法
1.满足filterDefinition 或者满足filterDefinition1
var builder = Builders<product>.Filter;
FilterDefinition<product> filterDefinition = builder.And(
builder.Eq(r => r.name, "33")
);
FilterDefinition<product> filterDefinition1 = builder.And(
builder.Eq(r => r.name, "44")
);
filterDefinition = filterDefinition | filterDefinition1;
2.满足filterDefinition 同时满足filterDefinition1
var builder = Builders<product>.Filter;
FilterDefinition<product> filterDefinition = builder.And(
builder.Eq(r => r.no, "11")
);
FilterDefinition<product> filterDefinition1 = builder.Or(
builder.Eq(r => r.name, "555"),
builder.Eq(r => r.name, "666"),
builder.Eq(r => r.name, "777")
);
filterDefinition = filterDefinition & filterDefinition1;
3正则表达式的使用
string p = name == null ? $".*{Regex.Escape("")}.*" : $".*{Regex.Escape(name)}.*"; //相当于like
string p = name == null ? $"^{Regex.Escape("")}.*" : $"^{Regex.Escape(name)}.*"; //相当于以12开头的查询
builder.Regex("name", new BsonRegularExpression(new Regex(p, RegexOptions.IgnoreCase)))
4.动态拼接条件
var builder = Builders<product>.Filter;
FilterDefinition<product> filtersUnion = builder.Where(m=>true);
if (!string.IsNullOrWhiteSpace(no))
{
filtersUnion = builder.And(filtersUnion, builder.Eq(r => r.no, no));
}
if (!string.IsNullOrWhiteSpace(name))
{
FilterDefinition<product> filterDefinition = builder.And(
builder.Regex("name", new BsonRegularExpression(new Regex(p, RegexOptions.IgnoreCase)))
//builder.Eq(r => r.no, "21"),
//builder.Gte(l => l.create, Convert.ToDateTime("2021-09-09 00:00:00")),
//builder.Lte(l => l.create, Convert.ToDateTime("2021-09-09 23:59:59")),
//builder.Where(m => m.name.Contains("da"))//where拼接条件速度会很慢,需要bson转json,最好用builder.Regex代替
);
filtersUnion = builder.And(filtersUnion, filterDefinition);
}
in的动态拼接
IEnumerable<string> pros = new[] { "11", "333", "33" };
if (pros.Count() > 0)
{
FilterDefinition<product> filterDefinition = builder.In(m => m.pro, pros);
filtersUnion = builder.And(filtersUnion, filterDefinition);
}
5:lamdb的动态拼接条件
Expression<Func<product, bool>> expression = p => 1 == 1;
expression = expression.And<product>(p => p.name == "da" || p.name == "da");//(true&&(a or b))
List<product> pros = mongoDBHelper.Find<product>("product", expression).ToList();
6:并发测试
var taskList = new List<Task>();
for (int i = 0; i < 10; i++){
taskList.Add(Task.Run(() =>
List<product> pros1 = mongoDBHelper.Find<product>("product").ToList();
));
}
Task.WaitAll(taskList.ToArray());
7:删除 name == "11"或者name == "22"数据
Expression<Func<product, bool>> expression = p => 1 == 2;
expression = expression.Or<product>(p => p.name == "11");
expression = expression.Or<product>(p => p.name == "22");
string deleteMany = mongoDBHelper.DeleteMany<product>("product", expression);
8:修改数据
Expression<Func<product, bool>> expression = p => 1 == 1;
expression = expression.And<product>(p => p.name == "444" || p.name == "555");
var builder = Builders<product>.Update.Set("no", "11").Set("pro", "22");
string res = mongoDBHelper.UpdateMany<product>("product", expression, builder);
9:分页查询
var builder = Builders<product>.Filter;
FilterDefinition<product> filterDefinition = builder.Where(m => 1 == 1);
//FilterDefinition<product> filterDefinition = builder.And(
// builder.Eq(r => r.name, "kk")
// //builder.Eq(r => r.no, "21"),
// //builder.Gte(l => l.create, Convert.ToDateTime("2021-09-09 00:00:00")),
// //builder.Lte(l => l.create, Convert.ToDateTime("2021-09-09 23:59:59")),
// //builder.Where(m => m.name.Contains("da"))
// );
////mongdb单机查询150万条数据用时6.701秒
var sortbuilder = Builders<product>.Sort;
var sort = sortbuilder.Descending("age1").Ascending("age");
string[] field = { "name", "no", "age", "age1" };
List<product> pros1 = mongoDBHelper.GetProductSkip<product>("product", filterDefinition, sort, field).ToList();
(三)依赖的lamdb帮助类
public static class ExpressionBuilder
{
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> first,
Expression<Func<T, bool>> second)
{
return first.AndAlso<T>(second, Expression.AndAlso);
}
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> first,
Expression<Func<T, bool>> second)
{
return first.AndAlso<T>(second, Expression.OrElse);
}
private static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2, Func<Expression, Expression, BinaryExpression> func)
{
var parameter = Expression.Parameter(typeof(T));
//var parameter2 = Expression.Parameter(typeof(T));
var ddd = expr1.Parameters;
var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
var left = leftVisitor.Visit(expr1.Body);
var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);//不是用.Parameters[0]结果是不对的
var right = rightVisitor.Visit(expr2.Body);
return Expression.Lambda<Func<T, bool>>(func(left, right), parameter);
///return Expression.Lambda(func(left, right), parameter);
}
private class ReplaceExpressionVisitor
: ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;
public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}
public override Expression Visit(Expression node)
{
if (node == _oldValue)
return _newValue;
return base.Visit(node);
}
}
注意点:
如果实体中包含得字段和mongdb存储得字段不一致,类上面必须加
[BsonIgnoreExtraElements]
public class product
MongoDB里存储的时间是格林尼治时间, 插入8:00, 查询时会发现变成了0:00,所以定义时间属性的时候需要加个标签
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
public DateTime? create { get; set; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现