diff --git a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Entities/Dependencies/IMongoDBEntity.cs b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Entities/Dependencies/IMongoDBEntity.cs
new file mode 100644
index 0000000000000000000000000000000000000000..330280ec359db154cc35129f99254a4a6a2edbb5
--- /dev/null
+++ b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Entities/Dependencies/IMongoDBEntity.cs
@@ -0,0 +1,30 @@
+// Copyright (c) 2020-2021 百小僧, Baiqian Co.,Ltd.
+// Furion is licensed under Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
+// You may obtain a copy of Mulan PSL v2 at:
+// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+// See the Mulan PSL v2 for more details.
+
+using MongoDB.Bson.Serialization.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MongoDB.Driver
+{
+ ///
+ ///
+ ///
+ public interface IMongoDBEntity
+ {
+ ///
+ /// Gets or sets the Id of the Entity.
+ ///
+ /// Id of the Entity.
+ [BsonId]
+ TKey Id { get; set; }
+ }
+}
diff --git a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/IAsyncCursorSourceExtensions.cs b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/IAsyncCursorSourceExtensions.cs
new file mode 100644
index 0000000000000000000000000000000000000000..40d082314845819f4ba6e6187280689248438c56
--- /dev/null
+++ b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/IAsyncCursorSourceExtensions.cs
@@ -0,0 +1,164 @@
+// Copyright (c) 2020-2021 百小僧, Baiqian Co.,Ltd.
+// Furion is licensed under Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
+// You may obtain a copy of Mulan PSL v2 at:
+// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+// See the Mulan PSL v2 for more details.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MongoDB.Driver
+{
+ ///
+ /// MongoDB 拓展方法
+ ///
+ public static partial class IAsyncCursorSourceExtensions
+ {
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static TNewProjection FirstOrDefault(this IFindFluent entities, Expression> projection)
+ {
+ return entities.Project(projection).FirstOrDefault();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task FirstOrDefaultAsync(this IFindFluent entities, Expression> projection)
+ {
+ return await entities.Project(projection).FirstOrDefaultAsync();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static List ToList(this IFindFluent entities, Expression> projection)
+ {
+ return entities.Project(projection).ToList();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task> ToListAsync(this IFindFluent entities, Expression> projection)
+ {
+ return await entities.Project(projection).ToListAsync();
+ }
+
+ ///
+ /// 分页拓展
+ ///
+ ///
+ ///
+ /// 页码,必须大于0
+ ///
+ ///
+ public static MongoDBPagedList ToPagedList(this IFindFluent entities, int pageIndex = 1, int pageSize = 20)
+ {
+ return entities.ToPagedList(a => a, pageIndex, pageSize);
+ }
+
+ ///
+ /// 分页拓展
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// 页码,必须大于0
+ ///
+ ///
+ public static MongoDBPagedList ToPagedList(this IFindFluent entities, Expression> projection, int pageIndex = 1, int pageSize = 20)
+ {
+ if (pageIndex <= 0) throw new InvalidOperationException($"{nameof(pageIndex)} must be a positive integer greater than 0.");
+
+ var totalCount = entities.CountDocuments();
+ var items = entities.Skip((pageIndex - 1) * pageSize).Limit(pageSize).Project(projection).ToEnumerable();
+ var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
+
+ return new MongoDBPagedList
+ {
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ Items = items,
+ TotalCount = (int)totalCount,
+ TotalPages = totalPages,
+ HasNextPages = pageIndex < totalPages,
+ HasPrevPages = pageIndex - 1 > 0
+ };
+ }
+
+ ///
+ /// 分页拓展
+ ///
+ ///
+ ///
+ /// 页码,必须大于0
+ ///
+ ///
+ ///
+ public static async Task> ToPagedListAsync(this IFindFluent entities, int pageIndex = 1, int pageSize = 20, CancellationToken cancellationToken = default)
+ {
+ return await entities.ToPagedListAsync(a => a, pageIndex, pageSize);
+ }
+
+ ///
+ /// 分页拓展
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// 页码,必须大于0
+ ///
+ ///
+ ///
+ public static async Task> ToPagedListAsync(this IFindFluent entities, Expression> projection, int pageIndex = 1, int pageSize = 20, CancellationToken cancellationToken = default)
+ {
+ if (pageIndex <= 0) throw new InvalidOperationException($"{nameof(pageIndex)} must be a positive integer greater than 0.");
+
+ var totalCount = await entities.CountDocumentsAsync();
+ var items = entities.Skip((pageIndex - 1) * pageSize).Limit(pageSize).Project(projection).ToEnumerable();
+ var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
+
+ return new MongoDBPagedList
+ {
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ Items = items,
+ TotalCount = (int)totalCount,
+ TotalPages = totalPages,
+ HasNextPages = pageIndex < totalPages,
+ HasPrevPages = pageIndex - 1 > 0
+ };
+ }
+ }
+}
diff --git a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/MongoDBServiceCollectionExtensions.cs b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/MongoDBServiceCollectionExtensions.cs
index 66365a6c9f28394d919e6dca9b48394265f1095f..74f5af98533f114109a992d2b1e024a987aa41e1 100644
--- a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/MongoDBServiceCollectionExtensions.cs
+++ b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Extensions/MongoDBServiceCollectionExtensions.cs
@@ -15,6 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection
///
public static class MongoDBServiceCollectionExtensions
{
+ private const string defaultDbName = "furion";
///
/// 添加 MongoDB 拓展
///
@@ -24,13 +25,16 @@ namespace Microsoft.Extensions.DependencyInjection
public static IServiceCollection AddMongoDB(this IServiceCollection services, string connectionString)
{
// 创建数据库连接对象
- services.AddScoped(u =>
+ services.AddScoped(u =>
{
- return new MongoClient(connectionString);
+ var mongoUrl = new MongoUrl(connectionString);
+ var dbName = mongoUrl.DatabaseName ?? defaultDbName;
+ return new MongoClient(connectionString).GetDatabase(dbName);
});
// 注册 MongoDB 仓储
services.AddScoped();
+ services.AddScoped(typeof(IMongoDBRepository<,>), typeof(MongoDBRepository<,>));
return services;
}
@@ -40,17 +44,19 @@ namespace Microsoft.Extensions.DependencyInjection
///
///
///
+ /// 数据库名称
///
- public static IServiceCollection AddMongoDB(this IServiceCollection services, MongoClientSettings settings)
+ public static IServiceCollection AddMongoDB(this IServiceCollection services, MongoClientSettings settings,string dbName="furion")
{
// 创建数据库连接对象
- services.AddScoped(u =>
+ services.AddScoped(u =>
{
- return new MongoClient(settings);
+ return new MongoClient(settings).GetDatabase(dbName);
});
// 注册 MongoDB 仓储
services.AddScoped();
+ services.AddScoped(typeof(IMongoDBRepository<,>), typeof(MongoDBRepository<,>));
return services;
}
@@ -64,13 +70,15 @@ namespace Microsoft.Extensions.DependencyInjection
public static IServiceCollection AddMongoDB(this IServiceCollection services, MongoUrl url)
{
// 创建数据库连接对象
- services.AddScoped(u =>
+ services.AddScoped(u =>
{
- return new MongoClient(url);
+ var dbName = url.DatabaseName ?? defaultDbName;
+ return new MongoClient(url).GetDatabase(dbName);
});
// 注册 MongoDB 仓储
services.AddScoped();
+ services.AddScoped(typeof(IMongoDBRepository<,>), typeof(MongoDBRepository<,>));
return services;
}
diff --git a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Internal/MongoDBPagedList.cs b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Internal/MongoDBPagedList.cs
new file mode 100644
index 0000000000000000000000000000000000000000..40bf72d9338255213ca9e9227b6393662b263af3
--- /dev/null
+++ b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Internal/MongoDBPagedList.cs
@@ -0,0 +1,58 @@
+// Copyright (c) 2020-2021 百小僧, Baiqian Co.,Ltd.
+// Furion is licensed under Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
+// You may obtain a copy of Mulan PSL v2 at:
+// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+// See the Mulan PSL v2 for more details.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MongoDB.Driver
+{
+ ///
+ /// 分页泛型集合
+ ///
+ ///
+ public class MongoDBPagedList
+ {
+ ///
+ /// 页码
+ ///
+ public int PageIndex { get; set; }
+
+ ///
+ /// 页容量
+ ///
+ public int PageSize { get; set; }
+
+ ///
+ /// 总条数
+ ///
+ public int TotalCount { get; set; }
+
+ ///
+ /// 总页数
+ ///
+ public int TotalPages { get; set; }
+
+ ///
+ /// 当前页集合
+ ///
+ public IEnumerable Items { get; set; }
+
+ ///
+ /// 是否有上一页
+ ///
+ public bool HasPrevPages { get; set; }
+
+ ///
+ /// 是否有下一页
+ ///
+ public bool HasNextPages { get; set; }
+ }
+}
diff --git a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/IMongoDBRepository.cs b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/IMongoDBRepository.cs
index 858af36f3d9a228529b55c412e3ae4e85aa842b9..2b8980855556c61b0ae172bdf5696a67a45ae61d 100644
--- a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/IMongoDBRepository.cs
+++ b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/IMongoDBRepository.cs
@@ -1,17 +1,24 @@
// Copyright (c) 2020-2021 百小僧, Baiqian Co.,Ltd.
// Furion is licensed under Mulan PSL v2.
-// You can use this software according to the terms and conditions of the Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
-// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
-// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
+using MongoDB.Bson;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+
namespace MongoDB.Driver
{
///
/// MongoDB 仓储
///
- public interface IMongoDBRepository
+ public partial interface IMongoDBRepository
{
///
/// 连接上下文
@@ -30,5 +37,390 @@ namespace MongoDB.Driver
///
///
IMongoDatabase GetDatabase(string name, MongoDatabaseSettings settings = null);
+
+ ///
+ /// 切换仓储
+ ///
+ /// 实体类型
+ /// 主键类型
+ /// 仓储
+ IMongoDBRepository Change()
+ where TDocument : class, IMongoDBEntity, new()
+ where TKey : class;
+ }
+
+ ///
+ /// MongoDB 泛型仓储
+ ///
+ ///
+ ///
+ public partial interface IMongoDBRepository
+ where TDocument : IMongoDBEntity, new()
+ where TKey : class
+ {
+ ///
+ /// 文档集合
+ ///
+ public IMongoCollection Entities { get; }
+
+ ///
+ /// 连接上下文
+ ///
+ MongoClient Context { get; }
+
+ ///
+ /// 动态连接上下文
+ ///
+ dynamic DynamicContext { get; }
+
+ ///
+ /// 判断是否存在
+ ///
+ /// 条件
+ ///
+ bool Exists(Expression> predicate);
+
+ ///
+ /// 判断是否存在
+ ///
+ /// 条件
+ ///
+ Task ExistsAsync(Expression> predicate);
+
+ ///
+ /// 获取记录数
+ ///
+ ///
+ long Count();
+
+ ///
+ /// 异步获取记录数
+ ///
+ ///
+ Task CountAsync();
+
+ ///
+ /// 获取记录数
+ ///
+ ///
+ long Count(Expression> expression);
+
+ ///
+ /// 异步获取记录数
+ ///
+ ///
+ Task CountAsync(Expression> expression);
+
+ ///
+ /// 获取记录数
+ ///
+ ///
+ long Count(FilterDefinition filter);
+
+ ///
+ /// 异步获取记录数
+ ///
+ ///
+ Task CountAsync(FilterDefinition filter);
+
+ ///
+ /// 获取单个对象
+ ///
+ /// objectId
+ ///
+ TDocument Get(TKey id);
+
+ ///
+ /// 获取单个对象
+ ///
+ /// 筛选条件
+ ///
+ TDocument Get(Expression> expression);
+
+ ///
+ /// 获取单个对象
+ ///
+ /// 过滤器
+ ///
+ TDocument Get(FilterDefinition filter);
+
+ ///
+ /// 异步获取单个对象
+ ///
+ /// objectId
+ ///
+ Task GetAsync(TKey id);
+
+ ///
+ /// 异步获取单个对象
+ ///
+ /// 筛选条件
+ ///
+ Task GetAsync(Expression> expression);
+
+ ///
+ /// 异步获取单个对象
+ ///
+ /// 过滤器
+ ///
+ Task GetAsync(FilterDefinition filter);
+
+ ///
+ /// 插入
+ ///
+ /// 对象
+ void Insert(TDocument value);
+
+ ///
+ /// 异步插入
+ ///
+ /// 对象
+ ///
+ Task InsertAsync(TDocument value);
+
+ ///
+ /// 批量插入
+ ///
+ /// 对象集合
+ void BatchInsert(IEnumerable values);
+
+ ///
+ /// 异步批量插入
+ ///
+ /// 对象集合
+ ///
+ Task BatchInsertAsync(IEnumerable values);
+
+ ///
+ /// 局部更新
+ ///
+ /// 记录ID
+ /// 更新条件
+ ///
+ UpdateResult Update(TKey id, UpdateDefinition update);
+
+ ///
+ /// 局部更新
+ ///
+ /// 记录ID
+ /// 更新条件
+ ///
+ Task UpdateAsync(TKey id, UpdateDefinition update);
+
+ ///
+ /// 局部更新
+ ///
+ /// 过滤器
+ /// 更新条件
+ ///
+ UpdateResult Update(FilterDefinition filter, UpdateDefinition update);
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ ///
+ /// 过滤器
+ /// 更新条件
+ ///
+ Task UpdateAsync(FilterDefinition filter, UpdateDefinition update);
+
+ ///
+ /// 局部更新(仅更新一条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ UpdateResult Update(Expression> expression,
+ UpdateDefinition update);
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ Task UpdateAsync(Expression> expression,
+ UpdateDefinition update);
+
+ ///
+ /// 局部更新(更新多条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ UpdateResult UpdateMany(Expression> expression,
+ UpdateDefinition update);
+
+ ///
+ /// 异步局部更新(更新多条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ Task UpdateManyAsync(Expression> expression,
+ UpdateDefinition update);
+
+ ///
+ /// 局部更新(仅更新一条记录)
+ /// x.Id == 1 && x.Age > 18 && x.Gender == 0]]>
+ /// new T{ RealName = "Ray", Gender = 1}]]>
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ UpdateResult Update(Expression> expression,
+ Expression> entity);
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ /// x.Id == 1 && x.Age > 18 && x.Gender == 0]]>
+ /// new T{ RealName = "Ray", Gender = 1}]]>
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ Task UpdateAsync(Expression> expression,
+ Expression> entity);
+
+ ///
+ /// 覆盖更新
+ ///
+ /// 对象
+ ///
+ ReplaceOneResult Update(TDocument value);
+
+ ///
+ /// 异步覆盖更新
+ ///
+ /// 对象
+ ///
+ Task UpdateAsync(TDocument value);
+
+ ///
+ /// 删除指定对象
+ ///
+ /// 对象Id
+ ///
+ DeleteResult Delete(TKey id);
+
+ ///
+ /// 异步删除指定对象
+ ///
+ /// 对象Id
+ ///
+ Task DeleteAsync(TKey id);
+
+ ///
+ /// 删除指定对象
+ ///
+ /// 查询条件
+ ///
+ DeleteResult Delete(Expression> expression);
+
+ ///
+ /// 异步删除指定对象
+ ///
+ /// 查询条件
+ ///
+ Task DeleteAsync(Expression> expression);
+
+ ///
+ /// 批量删除对象
+ ///
+ /// ID集合
+ ///
+ DeleteResult BatchDelete(IEnumerable ids);
+
+ ///
+ /// 异步批量删除对象
+ ///
+ /// ID集合
+ ///
+ Task BatchDeleteAsync(IEnumerable ids);
+
+ ///
+ /// 批量删除对象
+ ///
+ /// 过滤器
+ ///
+ DeleteResult BatchDelete(FilterDefinition filter);
+
+ ///
+ /// 异步批量删除对象
+ ///
+ /// 过滤器
+ ///
+ Task BatchDeleteAsync(FilterDefinition filter);
+
+ ///
+ /// 批量删除对象
+ ///
+ /// 筛选条件
+ ///
+ DeleteResult BatchDelete(Expression> expression);
+
+ ///
+ /// 异步批量删除对象
+ ///
+ /// 筛选条件
+ ///
+ Task BatchDeleteAsync(Expression> expression);
+
+ ///
+ /// 切换仓储
+ ///
+ /// 实体类型
+ /// 主键类型
+ /// 仓储
+ IMongoDBRepository Change()
+ where TChangeEntity : class, IMongoDBEntity, new()
+ where TChangeKey : class;
+
+ ///
+ /// 根据表达式查询多条记录
+ ///
+ /// 筛选条件
+ ///
+ IQueryable Where(Expression> predicate);
+
+ ///
+ /// 构建查询分析器
+ ///
+ ///
+ IQueryable AsQueryable();
+
+ ///
+ /// 构建查询分析器
+ ///
+ /// 筛选条件
+ ///
+ IQueryable AsQueryable(Expression> predicate);
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ ///
+ List AsEnumerable();
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ ///
+ Task> AsAsyncEnumerable();
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ /// 筛选条件
+ ///
+
+ List AsEnumerable(Expression> predicate);
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ /// 筛选条件
+ ///
+
+ Task> AsAsyncEnumerable(Expression> predicate);
}
}
\ No newline at end of file
diff --git a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/MongoDBRepository.cs b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/MongoDBRepository.cs
index 1787d2eb350cd285dc7988084dab6862cf76b94e..ade452bb75ca7d8629cf997b03e6685ced15666d 100644
--- a/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/MongoDBRepository.cs
+++ b/framework/Furion.Extras.DatabaseAccessor.MongoDB/Repositories/MongoDBRepository.cs
@@ -1,25 +1,39 @@
// Copyright (c) 2020-2021 百小僧, Baiqian Co.,Ltd.
// Furion is licensed under Mulan PSL v2.
-// You can use this software according to the terms and conditions of the Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
-// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
-// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+// https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
+using Microsoft.Extensions.DependencyInjection;
+using MongoDB.Bson;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+
namespace MongoDB.Driver
{
///
/// MongoDB 仓储
///
- public class MongoDBRepository : IMongoDBRepository
+ public partial class MongoDBRepository : IMongoDBRepository
{
+ ///
+ /// 服务提供器
+ ///
+ private readonly IServiceProvider _serviceProvider;
+
///
/// 构造函数
///
- ///
- public MongoDBRepository(IMongoClient mongoClient)
+ /// 服务提供器
+ public MongoDBRepository(IServiceProvider serviceProvider, IMongoDatabase db)
{
- DynamicContext = Context = (MongoClient)mongoClient;
+ _serviceProvider = serviceProvider;
+ DynamicContext = Context = (MongoClient)db.Client;
}
///
@@ -42,5 +56,625 @@ namespace MongoDB.Driver
{
return Context.GetDatabase(name, settings);
}
+
+ ///
+ /// 切换仓储
+ ///
+ /// 实体类型
+ /// 主键类型
+ /// 仓储
+ public virtual IMongoDBRepository Change()
+ where TDocument : class, IMongoDBEntity, new()
+ where TKey : class
+ {
+ return _serviceProvider.GetService>();
+ }
+ }
+
+ ///
+ /// MongoDB 泛型仓储
+ ///
+ ///
+ ///
+ public partial class MongoDBRepository : IMongoDBRepository
+ where TDocument : class, IMongoDBEntity, new()
+ where TKey : class
+ {
+ ///
+ /// 非泛型 MongoDB 仓储
+ ///
+ private readonly IMongoDBRepository _mongoDBRepository;
+
+ ///
+ /// 构造函数
+ ///
+ ///
+ ///
+ public MongoDBRepository(IMongoDBRepository mongoDBRepository, IMongoDatabase db)
+ {
+ _mongoDBRepository = mongoDBRepository;
+
+ DynamicContext = Context = (MongoClient)db.Client;
+ Entities = db.GetCollection(typeof(TDocument).Name);
+ }
+
+ ///
+ /// 文档集合
+ ///
+ public IMongoCollection Entities { get; }
+
+ ///
+ /// 数据库上下文
+ ///
+ public virtual MongoClient Context { get; }
+
+ ///
+ /// 动态数据库上下文
+ ///
+ public virtual dynamic DynamicContext { get; }
+
+ ///
+ /// 根据表达式查询多条记录
+ ///
+ ///
+ ///
+ public virtual IQueryable Where(Expression> predicate)
+ {
+ return AsQueryable(predicate);
+ }
+
+ ///
+ /// 构建查询分析器
+ ///
+ ///
+ public virtual IQueryable AsQueryable()
+ {
+ return Entities.AsQueryable();
+ }
+
+ ///
+ /// 构建查询分析器
+ ///
+ ///
+ ///
+ public virtual IQueryable AsQueryable(Expression> predicate)
+ {
+ return Entities.AsQueryable().Where(predicate);
+ }
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ ///
+ public virtual List AsEnumerable()
+ {
+ return AsQueryable().ToList();
+ }
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ ///
+ ///
+ public virtual List AsEnumerable(Expression> predicate)
+ {
+ return AsQueryable(predicate).ToList();
+ }
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ ///
+ public async virtual Task> AsAsyncEnumerable()
+ {
+ return await Task.FromResult(AsQueryable().ToList());
+ }
+
+ ///
+ /// 直接返回数据库结果
+ ///
+ ///
+ ///
+ public async virtual Task> AsAsyncEnumerable(Expression> predicate)
+ {
+ return await Task.FromResult(AsQueryable(predicate).ToList());
+ }
+
+ ///
+ /// 判断是否存在
+ ///
+ /// 条件
+ ///
+ public virtual bool Exists(Expression> predicate)
+ {
+ return Entities.AsQueryable().Any(predicate);
+ }
+
+ ///
+ /// 判断是否存在
+ ///
+ /// 条件
+ ///
+ public async virtual Task ExistsAsync(Expression> predicate)
+ {
+ return await Task.FromResult(Entities.AsQueryable().Any(predicate));
+ }
+
+ ///
+ /// 获取记录数
+ ///
+ ///
+ public virtual long Count()
+ {
+ return Count(new BsonDocument());
+ }
+
+ ///
+ /// 获取记录数
+ ///
+ ///
+ public virtual long Count(Expression> expression)
+ {
+ return Entities.CountDocuments(expression);
+ }
+
+ ///
+ /// 获取记录数
+ ///
+ /// 过滤器
+ ///
+ public virtual long Count(FilterDefinition filter)
+ {
+ return Entities.CountDocuments(filter);
+ }
+
+ ///
+ /// 获取记录数
+ ///
+ ///
+ public async virtual Task CountAsync()
+ {
+ return await CountAsync(new BsonDocument());
+ }
+
+ ///
+ /// 获取记录数
+ ///
+ /// 筛选条件
+ ///
+ public async virtual Task CountAsync(Expression> expression)
+ {
+ return await Entities.CountDocumentsAsync(expression);
+ }
+
+ ///
+ /// 获取记录数
+ ///
+ /// 过滤器
+ ///
+ public async virtual Task CountAsync(FilterDefinition filter)
+ {
+ return await Entities.CountDocumentsAsync(filter);
+ }
+
+ #region 查询
+
+ ///
+ /// 获取单个对象
+ ///
+ /// objectId
+ ///
+ public virtual TDocument Get(TKey id)
+ {
+ return Get(Builders.Filter.Eq(d => d.Id, id));
+ }
+
+ ///
+ /// 获取单个对象
+ ///
+ /// 过滤器
+ ///
+ public virtual TDocument Get(FilterDefinition filter)
+ {
+ return Entities.Find(filter).FirstOrDefault();
+ }
+
+ ///
+ /// 获取单个对象
+ ///
+ /// 筛选条件
+ ///
+ public virtual TDocument Get(Expression> predicate)
+ {
+ return Entities.Find(predicate).FirstOrDefault();
+ }
+
+ ///
+ /// 异步获取单个对象
+ ///
+ /// objectId
+ ///
+ public async Task GetAsync(TKey id)
+ {
+ return await Entities.Find(Builders.Filter.Eq(d => d.Id, id)).FirstOrDefaultAsync();
+ }
+
+ ///
+ /// 异步获取单个对象
+ ///
+ /// 过滤器
+ ///
+ public virtual async Task GetAsync(FilterDefinition filter)
+ {
+ return await Entities.Find(filter).FirstOrDefaultAsync();
+ }
+
+ ///
+ /// 异步获取单个对象
+ ///
+ /// 筛选条件
+ ///
+ public virtual async Task GetAsync(Expression> predicate)
+ {
+ return await Entities.Find(predicate).FirstOrDefaultAsync();
+ }
+
+ #endregion 查询
+
+ #region 插入
+
+ ///
+ /// 插入
+ ///
+ /// 对象
+ public void Insert(TDocument value)
+ {
+ Entities.InsertOne(value);
+ }
+
+ ///
+ /// 异步插入
+ ///
+ /// 对象
+ ///
+ public async Task InsertAsync(TDocument value)
+ {
+ await Entities.InsertOneAsync(value);
+ }
+
+ ///
+ /// 批量插入
+ ///
+ /// 对象集合
+ public void BatchInsert(IEnumerable values)
+ {
+ Entities.InsertMany(values);
+ }
+
+ ///
+ /// 异步批量插入
+ ///
+ /// 对象集合
+ ///
+ public async Task BatchInsertAsync(IEnumerable values)
+ {
+ await Entities.InsertManyAsync(values);
+ }
+
+ #endregion 插入
+
+ #region 更新
+
+ ///
+ /// 覆盖更新
+ ///
+ /// 对象
+ ///
+ public virtual ReplaceOneResult Update(TDocument value)
+ {
+ return Entities.ReplaceOne(Builders.Filter.Eq(d => d.Id, value.Id), value);
+ }
+
+ ///
+ /// 局部更新
+ ///
+ /// 记录ID
+ /// 更新条件
+ ///
+ public virtual UpdateResult Update(TKey id, UpdateDefinition update)
+ {
+ return Update(Builders.Filter.Eq(d => d.Id, id), update);
+ }
+
+ ///
+ /// 局部更新
+ ///
+ /// 记录ID
+ /// 更新条件
+ ///
+ public async virtual Task UpdateAsync(TKey id, UpdateDefinition update)
+ {
+ return await UpdateAsync(Builders.Filter.Eq(d => d.Id, id), update);
+ }
+
+ ///
+ /// 局部更新
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ public virtual UpdateResult Update(Expression> expression, UpdateDefinition update)
+ {
+ return Entities.UpdateMany(expression, update);
+ }
+
+ ///
+ /// 局部更新
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ public virtual UpdateResult UpdateMany(Expression> expression, UpdateDefinition update)
+ {
+ return Entities.UpdateMany(expression, update);
+ }
+
+ ///
+ /// 局部更新
+ ///
+ /// 过滤器
+ /// 更新条件
+ ///
+ public virtual UpdateResult Update(FilterDefinition filter, UpdateDefinition update)
+ {
+ return Entities.UpdateOne(filter, update);
+ }
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ /// x.Id == 1 && x.Age > 18 && x.Gender == 0]]>
+ /// new T{ RealName = "Ray", Gender = 1}]]>
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ public virtual UpdateResult Update(Expression> expression, Expression> entity)
+ {
+ var fieldList = new List>();
+
+ var param = entity.Body as MemberInitExpression;
+ if (param != null)
+ {
+ foreach (var item in param.Bindings)
+ {
+ var propertyName = item.Member.Name;
+ object propertyValue = null;
+ var memberAssignment = item as MemberAssignment;
+ if (memberAssignment == null) continue;
+ if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
+ {
+ var constantExpression = memberAssignment.Expression as ConstantExpression;
+ if (constantExpression != null)
+ propertyValue = constantExpression.Value;
+ }
+ else
+ {
+ propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
+ }
+
+ if (propertyName != "_id") //实体键_id不允许更新
+ {
+ fieldList.Add(Builders.Update.Set(propertyName, propertyValue));
+ }
+ }
+ }
+ return Entities.UpdateOne(expression, Builders.Update.Combine(fieldList));
+ }
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ ///
+ /// 过滤器
+ /// 更新条件
+ ///
+ public async virtual Task UpdateAsync(FilterDefinition filter, UpdateDefinition update)
+ {
+ return await Entities.UpdateOneAsync(filter, update);
+ }
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ public async virtual Task UpdateAsync(Expression> expression,
+ UpdateDefinition update)
+ {
+ return await Entities.UpdateOneAsync(expression, update);
+ }
+
+ ///
+ /// 异步局部更新(仅更新多条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ public async virtual Task UpdateManyAsync(Expression> expression,
+ UpdateDefinition update)
+ {
+ return await Entities.UpdateManyAsync(expression, update);
+ }
+
+ ///
+ /// 异步局部更新(仅更新一条记录)
+ ///
+ /// 筛选条件
+ /// 更新条件
+ ///
+ public async virtual Task UpdateAsync(Expression> expression,
+ Expression> entity)
+ {
+ var fieldList = new List>();
+
+ var param = entity.Body as MemberInitExpression;
+ if (param != null)
+ {
+ foreach (var item in param.Bindings)
+ {
+ var propertyName = item.Member.Name;
+ object propertyValue = null;
+ var memberAssignment = item as MemberAssignment;
+ if (memberAssignment == null) continue;
+ if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
+ {
+ var constantExpression = memberAssignment.Expression as ConstantExpression;
+ if (constantExpression != null)
+ propertyValue = constantExpression.Value;
+ }
+ else
+ {
+ propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
+ }
+
+ if (propertyName != "_id") //实体键_id不允许更新
+ {
+ fieldList.Add(Builders.Update.Set(propertyName, propertyValue));
+ }
+ }
+ }
+ return await Entities.UpdateOneAsync(expression, Builders.Update.Combine(fieldList));
+ }
+
+ ///
+ /// 异步覆盖更新
+ ///
+ /// 对象
+ ///
+ public async virtual Task UpdateAsync(TDocument value)
+ {
+ return await Entities.ReplaceOneAsync(Builders.Filter.Eq(d => d.Id, value.Id), value);
+ }
+
+ #endregion 更新
+
+ #region 删除
+
+ ///
+ /// 删除指定对象
+ ///
+ /// 对象Id
+ ///
+ public virtual DeleteResult Delete(TKey id)
+ {
+ return Entities.DeleteOne(Builders.Filter.Eq(d => d.Id, id));
+ }
+
+ ///
+ /// 删除指定对象
+ ///
+ /// 查询条件
+ ///
+ public virtual DeleteResult Delete(Expression> expression)
+ {
+ return Entities.DeleteOne(expression);
+ }
+
+ ///
+ /// 异步删除指定对象
+ ///
+ /// 对象Id
+ ///
+ public async virtual Task DeleteAsync(TKey id)
+ {
+ return await Entities.DeleteOneAsync(Builders.Filter.Eq(d => d.Id, id));
+ }
+
+ ///
+ /// 异步删除指定对象
+ ///
+ /// 查询条件
+ ///
+ public async virtual Task DeleteAsync(Expression> expression)
+ {
+ return await Entities.DeleteOneAsync(expression);
+ }
+
+ ///
+ /// 批量删除对象
+ ///
+ /// ID集合
+ ///
+ public virtual DeleteResult BatchDelete(IEnumerable ids)
+ {
+ var filter = Builders.Filter.In("_id", ids);
+ return Entities.DeleteMany(filter);
+ }
+
+ ///
+ /// 批量删除对象
+ ///
+ /// 过滤器
+ ///
+ public virtual DeleteResult BatchDelete(FilterDefinition filter)
+ {
+ return Entities.DeleteMany(filter);
+ }
+
+ ///
+ /// 批量删除对象
+ ///
+ /// 筛选条件
+ ///
+ public virtual DeleteResult BatchDelete(Expression> expression)
+ {
+ return Entities.DeleteMany(expression);
+ }
+
+ ///
+ /// 异步批量删除对象
+ ///
+ /// ID集合
+ ///
+ public async virtual Task BatchDeleteAsync(IEnumerable ids)
+ {
+ var filter = Builders.Filter.In("_id", ids);
+ return await Entities.DeleteManyAsync(filter);
+ }
+
+ ///
+ /// 异步批量删除对象
+ ///
+ /// 过滤器
+ ///
+ public async virtual Task BatchDeleteAsync(FilterDefinition filter)
+ {
+ return await Entities.DeleteManyAsync(filter);
+ }
+
+ ///
+ /// 异步批量删除对象
+ ///
+ /// 筛选条件
+ ///
+ public async virtual Task BatchDeleteAsync(Expression> expression)
+ {
+ return await Entities.DeleteManyAsync(expression);
+ }
+
+ #endregion 删除
+
+ ///
+ /// 切换仓储
+ ///
+ /// 实体类型
+ /// 主键类型
+ /// 仓储
+ public virtual IMongoDBRepository Change()
+ where TChangeEntity : class, IMongoDBEntity, new()
+ where TChangeKey : class
+ {
+ return _mongoDBRepository.Change();
+ }
}
}
\ No newline at end of file