Kaynağa Gözat

编写mongoDB扩展,提供LINQ操作支持

dev/1.0.1
stevelee 2 yıl önce
ebeveyn
işleme
b6731770f7
4 değiştirilmiş dosya ile 840 ekleme ve 25 silme
  1. +699
    -0
      src/BPA.Component.MongoClient/BPA.Component.MongoClient/MongoDbExtensions.cs
  2. +62
    -13
      src/BPA.Component.MongoClient/BPA.Component.MongoClient/Repository/BaseMongoDbRepository.cs
  3. +61
    -4
      src/BPA.Component.MongoClient/BPA.Component.MongoClient/Repository/IBaseMongoDbRepository.cs
  4. +18
    -8
      src/BPA.Component.MongoClient/BPA.Component.MongoClientTester/Program.cs

+ 699
- 0
src/BPA.Component.MongoClient/BPA.Component.MongoClient/MongoDbExtensions.cs Dosyayı Görüntüle

@@ -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;
}
}
}

+ 62
- 13
src/BPA.Component.MongoClient/BPA.Component.MongoClient/Repository/BaseMongoDbRepository.cs Dosyayı Görüntüle

@@ -5,6 +5,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Newtonsoft.Json.Linq;

namespace BPA.Component.MongoClient.Repository;
@@ -12,8 +13,7 @@ namespace BPA.Component.MongoClient.Repository;
/// <summary>
/// MongoDb基础仓储
/// </summary>
public class BaseMongoDbRepository<TMongoDbClient, TDocument> : IBaseMongoDbRepository<TDocument>
where TMongoDbClient : BaseMongoDbClient<TMongoDbClient>
public class BaseMongoDbRepository<TMongoDbClient, TDocument> : IBaseMongoDbRepository<TDocument> where TMongoDbClient : BaseMongoDbClient<TMongoDbClient>
where TDocument : new()
{
/// <summary>
@@ -70,11 +70,11 @@ public class BaseMongoDbRepository<TMongoDbClient, TDocument> : IBaseMongoDbRepo
/// <param name="document"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
public async Task<int> AddAsync<TDocument>(TDocument document)
public int Add<TDocument>(TDocument document)
{
if (document == null) return 0;
var coll = _database.GetCollection<TDocument>(document.GetType().Name);
await coll.InsertOneAsync(document);
coll.InsertOne(document);

return 1;
}
@@ -85,16 +85,15 @@ public class BaseMongoDbRepository<TMongoDbClient, TDocument> : IBaseMongoDbRepo
/// </summary>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
public async Task<int> AddListAsync<TDocument>(IEnumerable<TDocument> documents)
public int AddList<TDocument>(IEnumerable<TDocument> documents)
{
if (documents == null) return 0;
var coll = _database.GetCollection<TDocument>(documents.First().GetType().Name);
await coll.InsertManyAsync(documents);
coll.InsertMany(documents);

return 1;
}


/// <summary>
/// 修改一个
/// </summary>
@@ -103,12 +102,62 @@ public class BaseMongoDbRepository<TMongoDbClient, TDocument> : IBaseMongoDbRepo
/// <param name="options"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public async Task<UpdateResult> UpdateOneAsync<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression, UpdateOptions options = null)
public UpdateResult UpdateOne<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression, UpdateOptions options = null)
{
if (document == null) throw new ArgumentNullException("null document");
return _database.GetCollection<TDocument>(document.GetType().Name).UpdateOne(document, whereExpression, options);
}

/// <summary>
/// 修改多个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <param name="options"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
public UpdateResult UpdateMany<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression, UpdateOptions options = null)
{
if (document == null) throw new ArgumentNullException("null document");
return _database.GetCollection<TDocument>(document.GetType().Name).UpdateMany(document, whereExpression, options);
}

/// <summary>
/// 删除一个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public DeleteResult DeleteOne<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression)
{
if (document == null) throw new ArgumentNullException("null document");
return _database.GetCollection<TDocument>(document.GetType().Name).DeleteOne<TDocument>(whereExpression);
}

/// <summary>
/// 删除多个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public DeleteResult DeleteMany<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression)
{
if (document == null) throw new ArgumentNullException("null document");
return _database.GetCollection<TDocument>(document.GetType().Name).DeleteMany<TDocument>(whereExpression);
}
/// <summary>
/// 查询扩展
/// </summary>
/// <param name="whereExpression"></param>
/// <returns></returns>
public IMongoQueryable<TDocument> Queryable<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression)
{
if (document == null) throw new ArgumentNullException("");
throw new NotImplementedException();
// return await _database
// .GetCollection<TDocument>(document.GetType().Name)
// .UpdateOneAsync(whereExpression, new JsonUpdateDefinition<TDocument>(document), options);
if (document == null) throw new ArgumentNullException("null document");
return _database.GetCollection<TDocument>(document.GetType().Name).AsQueryable().Where(whereExpression);
}
}

+ 61
- 4
src/BPA.Component.MongoClient/BPA.Component.MongoClient/Repository/IBaseMongoDbRepository.cs Dosyayı Görüntüle

@@ -1,5 +1,6 @@
using System.Linq.Expressions;
using MongoDB.Driver;
using MongoDB.Driver.Linq;

namespace BPA.Component.MongoClient.Repository;

@@ -8,11 +9,67 @@ namespace BPA.Component.MongoClient.Repository;
/// </summary>
public interface IBaseMongoDbRepository<TDocument> where TDocument : new()
{
MongoDB.Driver.MongoClient _mongoDbClient { get; }
/// <summary>
/// 插入一个
/// </summary>
/// <param name="document"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
int Add<TDocument>(TDocument document);

Task<int> AddAsync<TDocument>(TDocument document);
/// <summary>
/// 插入多个
/// </summary>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
int AddList<TDocument>(IEnumerable<TDocument> documents);

Task<int> AddListAsync<TDocument>(IEnumerable<TDocument> documents);
/// <summary>
/// 修改一个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <param name="options"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
UpdateResult UpdateOne<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression, UpdateOptions options = null);

Task<UpdateResult> UpdateOneAsync<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression, UpdateOptions options = null);
/// <summary>
/// 修改多个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <param name="options"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
UpdateResult UpdateMany<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression, UpdateOptions options = null);

/// <summary>
/// 删除一个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
DeleteResult DeleteOne<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression);

/// <summary>
/// 删除多个
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
DeleteResult DeleteMany<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression);

/// <summary>
/// 查询扩展
/// </summary>
/// <param name="document"></param>
/// <param name="whereExpression"></param>
/// <typeparam name="TDocument"></typeparam>
/// <returns></returns>
IMongoQueryable<TDocument> Queryable<TDocument>(TDocument document, Expression<Func<TDocument, bool>> whereExpression);
}

+ 18
- 8
src/BPA.Component.MongoClient/BPA.Component.MongoClientTester/Program.cs Dosyayı Görüntüle

@@ -5,6 +5,7 @@ using BPA.Component.MongoClientTester.Repositorys;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MongoDB.Bson;

namespace BPA.Component.MongoClientTester;

@@ -28,15 +29,15 @@ internal class Program

var data = new CorpInfo
{
// Id = 0,
Id = DateTime.Now.Ticks,
DB = long.MaxValue,
AddressInfos = new List<CorpAddressInfo>
{
new() {Id = DateTime.Now.Ticks, Latitude = 66.52, Longitude = 451.63, Address = "天府大道天府三街", Remark = "一号办公地点1"},
new() {Id = DateTime.Now.Ticks, Latitude = 66.52, Longitude = 451.63, Address = "天府大道天府五街", Remark = "二号办公地点1"},
},
Name = "太阳国11111",
No = "sun11111",
Name = "太阳国",
No = "sun",
Creator = new CorpAddressInfo {Id = DateTime.Now.Ticks, Latitude = 66.52, Longitude = 451.63, Address = "天府大道天府三街", Remark = "一号办公地点"},
Tags = new Dictionary<string, object>
{
@@ -51,9 +52,9 @@ internal class Program
};

// 添加一个
// await userRepository.AddAsync(data);
// 添加多个
// await userRepository.AddListAsync(new List<CorpInfo>()
// userRepository.Add(data);
// // 添加多个
// userRepository.AddList(new List<CorpInfo>
// {
// new()
// {
@@ -102,8 +103,17 @@ internal class Program
// Phones = new List<string> {"1921682012", "1921682012", "1921682012"}
// }
// });

await userRepository.UpdateOneAsync(data, info => info.CorpId == 1);
// // 更新一个
// userRepository.UpdateOne(data, info => info.Id == 637843434739905640);
// // 更新多个
// userRepository.UpdateMany(data, info => info.Id == 637843434739905640);
// 删除一个
// userRepository.DeleteOne(data, info => info.Id == 637843434739905640);
// 删除多个
// userRepository.DeleteMany(data, info => info.Id == 637843460358762663);
// 查询
var dd = userRepository.Queryable(data, info => info.Id == 0).ToList();
Console.WriteLine(dd.ToJson());
}
}



Yükleniyor…
İptal
Kaydet