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