|
|
@@ -0,0 +1,699 @@ |
|
|
|
using System.Linq.Expressions; |
|
|
|
using MongoDB.Bson; |
|
|
|
using MongoDB.Driver; |
|
|
|
using MongoDB.Driver.Linq; |
|
|
|
|
|
|
|
namespace BPA.Component.MongoClient |
|
|
|
{ |
|
|
|
/// <summary> |
|
|
|
/// MongoDB 文件集扩展类 |
|
|
|
/// </summary> |
|
|
|
public static class MongoDbExtensions |
|
|
|
{ |
|
|
|
/// <summary> |
|
|
|
/// 聚合默认选项 |
|
|
|
/// </summary> |
|
|
|
public static readonly AggregateOptions DefaultAggregateOptions = new AggregateOptions {AllowDiskUse = true}; |
|
|
|
|
|
|
|
#region 文档集操作扩展 |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 创建文档集索引,倒序 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="indexFields"></param> |
|
|
|
/// <param name="model"></param> |
|
|
|
/// <param name="options"></param> |
|
|
|
public static void CreateIndex<TDocument>(this IMongoCollection<TDocument> collection, string[] indexFields, CreateIndexModel<TDocument> model, CreateOneIndexOptions options = null) |
|
|
|
{ |
|
|
|
if (indexFields == null) |
|
|
|
return; |
|
|
|
var indexKeys = Builders<TDocument>.IndexKeys; |
|
|
|
IndexKeysDefinition<TDocument> keys = null; |
|
|
|
if (indexFields.Length > 0) |
|
|
|
{ |
|
|
|
keys = indexKeys.Descending(indexFields[0]); |
|
|
|
} |
|
|
|
|
|
|
|
for (var i = 1; i < indexFields.Length; i++) |
|
|
|
{ |
|
|
|
var strIndex = indexFields[i]; |
|
|
|
keys = keys.Descending(strIndex); |
|
|
|
} |
|
|
|
|
|
|
|
if (keys != null) |
|
|
|
{ |
|
|
|
collection.Indexes.CreateOne(model, options); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
// #region 插入扩展 |
|
|
|
// |
|
|
|
// /// <summary> |
|
|
|
// /// 插入一个 ,等同使用:<code>IMongoCollection.InsertOne</code> |
|
|
|
// /// </summary> |
|
|
|
// /// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
// /// <param name="collection">文档集</param> |
|
|
|
// /// <param name="document">文档对象</param> |
|
|
|
// /// <param name="options">插入配置选项</param> |
|
|
|
// public static void InsertOne<TDocument>(this IMongoCollection<TDocument> collection, TDocument document, InsertOneOptions options = null) |
|
|
|
// { |
|
|
|
// collection.InsertOne(document, options, default); |
|
|
|
// } |
|
|
|
// |
|
|
|
// /// <summary> |
|
|
|
// /// 插入多个,等同使用: |
|
|
|
// /// <code>IMongoCollection.InsertMany(IClientSessionHandle, IEnumerable{TDocument}, InsertManyOptions, CancellationToken)</code> |
|
|
|
// /// </summary> |
|
|
|
// /// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
// /// <param name="collection">文档集</param> |
|
|
|
// /// <param name="documents">文档对象</param> |
|
|
|
// /// <param name="options">插入配置选项</param> |
|
|
|
// public static void InsertMany<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
// IEnumerable<TDocument> documents, |
|
|
|
// InsertManyOptions options = null) |
|
|
|
// { |
|
|
|
// collection.InsertMany(documents, options, default); |
|
|
|
// } |
|
|
|
// |
|
|
|
// #endregion |
|
|
|
|
|
|
|
#region 更新扩展 |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 构建更新操作定义 |
|
|
|
/// </summary> |
|
|
|
/// <param name="document">bsondocument文档</param> |
|
|
|
/// <param name="parent"></param> |
|
|
|
/// <returns></returns> |
|
|
|
private static List<UpdateDefinition<BsonDocument>> BuildUpdateDefinition(BsonDocument document, string parent) |
|
|
|
{ |
|
|
|
var updates = new List<UpdateDefinition<BsonDocument>>(); |
|
|
|
foreach (var element in document.Elements) |
|
|
|
{ |
|
|
|
var key = parent == null ? element.Name : $"{parent}.{element.Name}"; |
|
|
|
//子元素是对象 |
|
|
|
if (element.Value.IsBsonDocument) |
|
|
|
{ |
|
|
|
updates.AddRange(BuildUpdateDefinition(element.Value.ToBsonDocument(), key)); |
|
|
|
} |
|
|
|
//子元素是对象数组 |
|
|
|
else if (element.Value.IsBsonArray) |
|
|
|
{ |
|
|
|
var arrayDocs = element.Value.AsBsonArray; |
|
|
|
var i = 0; |
|
|
|
foreach (var doc in arrayDocs) |
|
|
|
{ |
|
|
|
if (doc.IsBsonDocument) |
|
|
|
{ |
|
|
|
updates.AddRange(BuildUpdateDefinition(doc.ToBsonDocument(), key + $".{i}")); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
updates.Add(Builders<BsonDocument>.Update.Set(f => f[key], element.Value)); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
i++; |
|
|
|
} |
|
|
|
} |
|
|
|
//子元素是其他 |
|
|
|
else |
|
|
|
{ |
|
|
|
updates.Add(Builders<BsonDocument>.Update.Set(f => f[key], element.Value)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return updates; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 更新满足条件的第一条数据, |
|
|
|
/// <code>IMongoCollection.UpdateOne(FilterDefinition{TDocument}, UpdateDefinition{TDocument}, UpdateOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="document"></param> |
|
|
|
/// <param name="whereExpression"></param> |
|
|
|
/// <param name="options"></param> |
|
|
|
public static UpdateResult UpdateOne<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression, |
|
|
|
UpdateOptions options = null) |
|
|
|
{ |
|
|
|
var bsonDocument = document.ToBsonDocument(); |
|
|
|
bsonDocument.Remove("_id"); |
|
|
|
BsonDocument update = new BsonDocument |
|
|
|
{ |
|
|
|
{"$set", bsonDocument} |
|
|
|
}; |
|
|
|
return collection.UpdateOne(whereExpression, update, options); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 更新满足条件的第一条数据, |
|
|
|
/// <code>IMongoCollection.UpdateOne(FilterDefinition{TDocument}, UpdateDefinition{TDocument}, UpdateOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="document"></param> |
|
|
|
/// <param name="whereExpression"></param> |
|
|
|
/// <param name="options"></param> |
|
|
|
public static Task<UpdateResult> UpdateOneAsync<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression, |
|
|
|
UpdateOptions options = null) |
|
|
|
{ |
|
|
|
var bsonDocument = document.ToBsonDocument(); |
|
|
|
bsonDocument.Remove("_id"); |
|
|
|
BsonDocument update = new BsonDocument |
|
|
|
{ |
|
|
|
{"$set", bsonDocument} |
|
|
|
}; |
|
|
|
return collection.UpdateOneAsync(whereExpression, update, options); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 更新满足条件的多条数据, |
|
|
|
/// <code>IMongoCollection.UpdateOne(FilterDefinition{TDocument}, UpdateDefinition{TDocument},UpdateOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="document"></param> |
|
|
|
/// <param name="whereExpression"></param> |
|
|
|
/// <param name="options"></param> |
|
|
|
public static UpdateResult UpdateMany<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression, |
|
|
|
UpdateOptions options = null) |
|
|
|
{ |
|
|
|
var bsonDocument = document.ToBsonDocument(); |
|
|
|
bsonDocument.Remove("_id"); |
|
|
|
BsonDocument update = new BsonDocument |
|
|
|
{ |
|
|
|
{"$set", bsonDocument} |
|
|
|
}; |
|
|
|
return collection.UpdateMany(whereExpression, update, options); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 更新满足条件的多条数据, |
|
|
|
/// <code>IMongoCollection.UpdateOne(FilterDefinition{TDocument}, UpdateDefinition{TDocument},UpdateOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="document"></param> |
|
|
|
/// <param name="whereExpression"></param> |
|
|
|
/// <param name="options"></param> |
|
|
|
public static Task<UpdateResult> UpdateManyAsync<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression, |
|
|
|
UpdateOptions options = null) |
|
|
|
{ |
|
|
|
var bsonDocument = document.ToBsonDocument(); |
|
|
|
bsonDocument.Remove("_id"); |
|
|
|
BsonDocument update = new BsonDocument |
|
|
|
{ |
|
|
|
{"$set", bsonDocument} |
|
|
|
}; |
|
|
|
return collection.UpdateManyAsync(whereExpression, update, options); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 根据更新字段表达式组装UpdateDefinitioons |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="param"></param> |
|
|
|
/// <returns></returns> |
|
|
|
private static List<UpdateDefinition<TDocument>> BuildUpdateDefinitioonsByExpression<TDocument>( |
|
|
|
MemberInitExpression param) |
|
|
|
{ |
|
|
|
var fieldList = new List<UpdateDefinition<TDocument>>(); |
|
|
|
foreach (var item in param.Bindings) |
|
|
|
{ |
|
|
|
var propertyName = item.Member.Name; |
|
|
|
if (propertyName == "_id" || propertyName == "Id") |
|
|
|
continue; |
|
|
|
object propertyValue = null; |
|
|
|
if (!(item is MemberAssignment memberAssignment)) |
|
|
|
continue; |
|
|
|
if (memberAssignment.Expression.NodeType == ExpressionType.Constant) |
|
|
|
{ |
|
|
|
if (memberAssignment.Expression is ConstantExpression constantExpression) |
|
|
|
propertyValue = constantExpression.Value; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (memberAssignment.Expression is MethodCallExpression methodCallExpression2) |
|
|
|
{ |
|
|
|
if (methodCallExpression2.Method.Name == "AddToSet") |
|
|
|
{ |
|
|
|
var argument = methodCallExpression2.Arguments[1]; |
|
|
|
if (argument is ConstantExpression constantExpression) |
|
|
|
{ |
|
|
|
fieldList.Add( |
|
|
|
Builders<TDocument>.Update.AddToSet(propertyName, constantExpression.Value)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
propertyValue = Expression.Lambda(argument, null).Compile().DynamicInvoke(); |
|
|
|
if (propertyValue is IEnumerable<object> lsArg) |
|
|
|
{ |
|
|
|
fieldList.Add(Builders<TDocument>.Update.AddToSetEach(propertyName, lsArg)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
fieldList.Add(Builders<TDocument>.Update.AddToSet(propertyName, propertyValue)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke(); |
|
|
|
fieldList.Add(Builders<TDocument>.Update.Set(propertyName, propertyValue)); |
|
|
|
} |
|
|
|
|
|
|
|
return fieldList; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 自定义字段更新 更新满足条件的第一条数据,实体键_id不允许更新 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">数据库实体类型</typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="whereExpression">更新条件</param> |
|
|
|
/// <param name="columnsExp">更新字段表达式:x=>new TDocument{ F1=1,F2=2 }</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static UpdateResult UpdateOne<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
Expression<Action<TDocument>> columnsExp, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
if (!(columnsExp.Body is MemberInitExpression param)) |
|
|
|
throw new ArgumentException($"{nameof(columnsExp)}错误,更新字段表达式示例: x=>new TDocument{{ F1 = 1,F2 = 2 }}"); |
|
|
|
List<UpdateDefinition<TDocument>> fieldList = BuildUpdateDefinitioonsByExpression<TDocument>(param); |
|
|
|
return collection.UpdateOne(whereExpression, Builders<TDocument>.Update.Combine(fieldList)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 自定义字段更新 更新满足条件的第一条数据,实体键_id不允许更新 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">数据库实体类型</typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="whereExpression">更新条件</param> |
|
|
|
/// <param name="columnsExp">更新字段表达式:x=>new TDocument{ F1=1,F2=2 }</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static Task<UpdateResult> UpdateOneAsync<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
Expression<Action<TDocument>> columnsExp, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
if (!(columnsExp.Body is MemberInitExpression param)) |
|
|
|
throw new ArgumentException($"{nameof(columnsExp)}错误,更新字段表达式示例: x=>new TDocument{{ F1 = 1,F2 = 2 }}"); |
|
|
|
List<UpdateDefinition<TDocument>> fieldList = BuildUpdateDefinitioonsByExpression<TDocument>(param); |
|
|
|
return collection.UpdateOneAsync(whereExpression, Builders<TDocument>.Update.Combine(fieldList)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 自定义字段更新 更新满足条件的多条数据,实体键_id不允许更新 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">数据库实体类型</typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="whereExpression">更新条件</param> |
|
|
|
/// <param name="columnsExp">更新字段表达式:x=>new TDocument{ F1=1,F2=2 }</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static UpdateResult UpdateMany<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
Expression<Action<TDocument>> columnsExp, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
if (!(columnsExp.Body is MemberInitExpression param)) |
|
|
|
throw new ArgumentException($"{nameof(columnsExp)}错误,更新字段表达式示例: x=>new TDocument{{ F1 = 1,F2 = 2 }}"); |
|
|
|
List<UpdateDefinition<TDocument>> fieldList = BuildUpdateDefinitioonsByExpression<TDocument>(param); |
|
|
|
return collection.UpdateMany(whereExpression, Builders<TDocument>.Update.Combine(fieldList)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 自定义字段更新 更新满足条件的多条数据,实体键_id不允许更新 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">数据库实体类型</typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="whereExpression">更新条件</param> |
|
|
|
/// <param name="columnsExp">更新字段表达式:x=>new TDocument{ F1=1,F2=2 }</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static Task<UpdateResult> UpdateManyAsync<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
Expression<Action<TDocument>> columnsExp, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
if (!(columnsExp.Body is MemberInitExpression param)) |
|
|
|
throw new ArgumentException($"{nameof(columnsExp)}错误,更新字段表达式示例: x=>new TDocument{{ F1 = 1,F2 = 2 }}"); |
|
|
|
List<UpdateDefinition<TDocument>> fieldList = BuildUpdateDefinitioonsByExpression<TDocument>(param); |
|
|
|
return collection.UpdateManyAsync(whereExpression, Builders<TDocument>.Update.Combine(fieldList)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 异步覆盖更新满足条件的第一条数据,主键字段名称必须是 Id,等同 |
|
|
|
/// <code>IMongoCollection.ReplaceOne(FilterDefinition{TDocument}, TDocument, ReplaceOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档对象类型</typeparam> |
|
|
|
/// <param name="collection">文档集操作接口</param> |
|
|
|
/// <param name="document">文档对象对象</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static ReplaceOneResult ReplaceOneById<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document) |
|
|
|
{ |
|
|
|
var id = new ObjectId(typeof(TDocument).GetProperty("Id").GetValue(document).ToString()); |
|
|
|
return collection.ReplaceOne(new BsonDocument("_id", id), document); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 异步覆盖更新满足条件的第一条数据,主键字段名称必须是 Id,等同 |
|
|
|
/// <code>IMongoCollection.ReplaceOne(FilterDefinition{TDocument}, TDocument, ReplaceOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档对象类型</typeparam> |
|
|
|
/// <param name="collection">文档集操作接口</param> |
|
|
|
/// <param name="document">文档对象对象</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static Task<ReplaceOneResult> ReplaceOneByIdAsync<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document) |
|
|
|
{ |
|
|
|
var id = new ObjectId(typeof(TDocument).GetProperty("Id").GetValue(document).ToString()); |
|
|
|
return collection.ReplaceOneAsync(new BsonDocument("_id", id), document); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 异步覆盖更新满足条件的第一条数据,主键字段名称必须是 ID,等同 |
|
|
|
/// <code>IMongoCollection.ReplaceOne(FilterDefinition{TDocument}, TDocument, ReplaceOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档对象类型</typeparam> |
|
|
|
/// <param name="collection">文档集操作接口</param> |
|
|
|
/// <param name="document">文档对象对象</param> |
|
|
|
/// <param name="whereExpression">查询添加表达式</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static ReplaceOneResult ReplaceOne<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
return collection.ReplaceOne(whereExpression, document); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 异步覆盖更新满足条件的第一条数据,主键字段名称必须是 ID,等同 |
|
|
|
/// <code>IMongoCollection.ReplaceOne(FilterDefinition{TDocument}, TDocument, ReplaceOptions, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档对象类型</typeparam> |
|
|
|
/// <param name="collection">文档集操作接口</param> |
|
|
|
/// <param name="document">文档对象对象</param> |
|
|
|
/// <param name="whereExpression">查询添加表达式</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static Task<ReplaceOneResult> ReplaceOneAsync<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
TDocument document, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
return collection.ReplaceOneAsync(whereExpression, document); |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 删除扩展 |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 删除满足条件的第一条数据,等同于 |
|
|
|
/// <code>IMongoCollection.DeleteOne(FilterDefinition{TDocument}, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档对象类型</typeparam> |
|
|
|
/// <param name="collection">文档集操作接口</param> |
|
|
|
/// <param name="whereExpression">删除条件表达式</param> |
|
|
|
public static DeleteResult DeleteOne<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
return collection.DeleteOne(whereExpression, null, default); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 批量删除满足条件的多条数据,等同于 |
|
|
|
/// <code>IMongoCollection.DeleteMany(FilterDefinition{TDocument}, CancellationToken)</code> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档对象类型</typeparam> |
|
|
|
/// <param name="collection">文档集操作接口</param> |
|
|
|
/// <param name="whereExpression">删除条件表达式</param> |
|
|
|
public static DeleteResult DeleteMany<TDocument>(this IMongoCollection<TDocument> collection, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
return collection.DeleteMany(whereExpression, null, default); |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 查询扩展 |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// AggregateWithDefautSortOption |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <param name="optionsAction"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public static IAggregateFluent<TDocument> AggregateWithDefautSortOption<TDocument>( |
|
|
|
this IMongoCollection<TDocument> collection, |
|
|
|
Action<AggregateOptions> optionsAction = null) |
|
|
|
{ |
|
|
|
var options = new AggregateOptions |
|
|
|
{ |
|
|
|
Collation = new Collation(locale: "zh", numericOrdering: true), |
|
|
|
AllowDiskUse = true |
|
|
|
}; |
|
|
|
if (optionsAction != null) |
|
|
|
optionsAction(options); |
|
|
|
return collection.Aggregate(options); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 可查询 <see cref="IMongoCollectionExtensions.AsQueryable{TDocument}(IMongoCollection{TDocument}, AggregateOptions)"/> |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <param name="collection"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public static IMongoQueryable<TDocument> Queryable<TDocument>(this IMongoCollection<TDocument> collection) |
|
|
|
{ |
|
|
|
return collection.AsQueryable(DefaultAggregateOptions); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 分页查询,统计总共多少条 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
/// <param name="queryable">可查询器</param> |
|
|
|
/// <param name="pageIndex">页码,第几页,默认1</param> |
|
|
|
/// <param name="pageSize">每页条数,默认10</param> |
|
|
|
/// <param name="total">总共多少条</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static List<TDocument> Pagination<TDocument>(this IQueryable<TDocument> queryable, int pageIndex, |
|
|
|
int pageSize, |
|
|
|
out int total) |
|
|
|
{ |
|
|
|
pageIndex = pageIndex < 0 ? 1 : pageIndex; |
|
|
|
pageSize = pageSize < 0 ? 10 : pageSize; |
|
|
|
total = queryable.Count(); |
|
|
|
return queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 分页查询,统计总共多少条,可以根据查询新对象的表达式,返回新对象集合 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
/// <typeparam name="TNewResult">新结构类型</typeparam> |
|
|
|
/// <param name="queryable">可查询器</param> |
|
|
|
/// <param name="selector">查询func,查询返回新对象的表达式</param> |
|
|
|
/// <param name="pageIndex">页码,第几页,默认1</param> |
|
|
|
/// <param name="pageSize">每页条数,默认10</param> |
|
|
|
/// <param name="total">总共多少条</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static List<TNewResult> Pagination<TDocument, TNewResult>(this IQueryable<TDocument> queryable, |
|
|
|
Expression<Func<TDocument, TNewResult>> selector, int pageIndex, int pageSize, out int total) |
|
|
|
{ |
|
|
|
pageIndex = pageIndex < 0 ? 1 : pageIndex; |
|
|
|
pageSize = pageSize < 0 ? 10 : pageSize; |
|
|
|
total = queryable.Count(); |
|
|
|
return queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(selector).ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 分页查询 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
/// <param name="queryable">可查询器</param> |
|
|
|
/// <param name="pageIndex">页码,第几页,默认1</param> |
|
|
|
/// <param name="pageSize">每页条数,默认10</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static List<TDocument> Pagination<TDocument>(this IQueryable<TDocument> queryable, int pageIndex, |
|
|
|
int pageSize) |
|
|
|
{ |
|
|
|
pageIndex = pageIndex < 0 ? 1 : pageIndex; |
|
|
|
pageSize = pageSize < 0 ? 10 : pageSize; |
|
|
|
return queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 分页查询,可以根据查询新对象的表达式,返回新对象集合 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
/// <typeparam name="TNewResult">新结构类型</typeparam> |
|
|
|
/// <param name="queryable">可查询器</param> |
|
|
|
/// <param name="selector">查询func,查询返回新对象的表达式</param> |
|
|
|
/// <param name="pageIndex">页码,第几页,默认1</param> |
|
|
|
/// <param name="pageSize">每页条数,默认10</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static List<TNewResult> Pagination<TDocument, TNewResult>(this IMongoQueryable<TDocument> queryable, |
|
|
|
Expression<Func<TDocument, TNewResult>> selector, int pageIndex, int pageSize) |
|
|
|
{ |
|
|
|
pageIndex = pageIndex < 0 ? 1 : pageIndex; |
|
|
|
pageSize = pageSize < 0 ? 10 : pageSize; |
|
|
|
return queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(selector).ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 当condition为true,才会执行where表达式里面的条件 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
/// <param name="queryable">可查询器</param> |
|
|
|
/// <param name="beforeCondition">前置条件</param> |
|
|
|
/// <param name="whereExpression">where表达式</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static IMongoQueryable<TDocument> WhereIF<TDocument>(this IMongoQueryable<TDocument> queryable, |
|
|
|
bool beforeCondition, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
if (beforeCondition) |
|
|
|
return queryable.Where(whereExpression); |
|
|
|
return queryable; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 当condition为true,才会执行where表达式里面的条件 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument">文档集类型</typeparam> |
|
|
|
/// <param name="queryable">可查询器</param> |
|
|
|
/// <param name="beforeCondition">前置条件</param> |
|
|
|
/// <param name="whereExpression">where表达式</param> |
|
|
|
/// <returns></returns> |
|
|
|
public static IQueryable<TDocument> WhereIF<TDocument>(this IQueryable<TDocument> queryable, |
|
|
|
bool beforeCondition, |
|
|
|
Expression<Func<TDocument, bool>> whereExpression) |
|
|
|
{ |
|
|
|
if (beforeCondition) |
|
|
|
return queryable.Where(whereExpression); |
|
|
|
return queryable; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 根据selectNewResultExp 表达式返回新的查询结果,最终要执行 必须ToList、Single、 Any |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <typeparam name="TProjection"></typeparam> |
|
|
|
/// <typeparam name="TNewResult"></typeparam> |
|
|
|
/// <param name="find"></param> |
|
|
|
/// <param name="selectNewResultExp"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public static IFindFluent<TDocument, TNewResult> As<TDocument, TProjection, TNewResult>( |
|
|
|
this IFindFluent<TDocument, TProjection> find, |
|
|
|
Expression<Func<TDocument, TNewResult>> selectNewResultExp) |
|
|
|
{ |
|
|
|
return find.Project(selectNewResultExp); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 根据selectNewResultExp 表达式返回新的查询结果,最终要执行 必须ToList、Single、 Any |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="TDocument"></typeparam> |
|
|
|
/// <typeparam name="TProjection"></typeparam> |
|
|
|
/// <typeparam name="TNewResult"></typeparam> |
|
|
|
/// <param name="find"></param> |
|
|
|
/// <param name="selectNewResultExp"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public static IFindFluent<TDocument, TNewResult> Select<TDocument, TProjection, TNewResult>( |
|
|
|
this IFindFluent<TDocument, TProjection> find, |
|
|
|
Expression<Func<TDocument, TNewResult>> selectNewResultExp) |
|
|
|
{ |
|
|
|
return find.Project(selectNewResultExp); |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 创建 查询 、索引、更新、排序 条件定义 |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 创建过滤条件定义 |
|
|
|
/// </summary> |
|
|
|
/// <param name="collection"></param> |
|
|
|
public static FilterDefinitionBuilder<TDocument> BuilderFilter<TDocument>( |
|
|
|
this IMongoCollection<TDocument> collection) |
|
|
|
{ |
|
|
|
return Builders<TDocument>.Filter; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 创建索引条件定义 |
|
|
|
/// </summary> |
|
|
|
/// <param name="collection"></param> |
|
|
|
public static IndexKeysDefinitionBuilder<TDocument> BuilderIndexKeys<TDocument>( |
|
|
|
this IMongoCollection<TDocument> collection) |
|
|
|
{ |
|
|
|
return Builders<TDocument>.IndexKeys; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 创建更新条件定义 |
|
|
|
/// </summary> |
|
|
|
/// <param name="collection"></param> |
|
|
|
public static UpdateDefinitionBuilder<TDocument> BuilderUpdate<TDocument>( |
|
|
|
this IMongoCollection<TDocument> collection) |
|
|
|
{ |
|
|
|
return Builders<TDocument>.Update; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 创建排序条件定义 |
|
|
|
/// </summary> |
|
|
|
/// <param name="collection"></param> |
|
|
|
public static SortDefinitionBuilder<TDocument> BuilderSort<TDocument>( |
|
|
|
this IMongoCollection<TDocument> collection) |
|
|
|
{ |
|
|
|
return Builders<TDocument>.Sort; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// AddToSet 追加到数组 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="T"></typeparam> |
|
|
|
/// <param name="source"></param> |
|
|
|
/// <param name="item"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public static List<T> AddToSet<T>(this List<T> source, T item) |
|
|
|
{ |
|
|
|
return new List<T> {item}; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// AddToSet 追加到数组 |
|
|
|
/// </summary> |
|
|
|
/// <typeparam name="T"></typeparam> |
|
|
|
/// <param name="source"></param> |
|
|
|
/// <param name="items"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public static List<T> AddToSet<T>(this List<T> source, List<T> items) |
|
|
|
{ |
|
|
|
return items; |
|
|
|
} |
|
|
|
} |
|
|
|
} |