第31章 CURD操作的泛型定义实现之IRepository<TEntity>

1 Data.IRepository<TEntity>

using Core;

using Core.Caching;

using Core.Domain;

namespace Data

{

    ///<typeparam name="TEntity">泛型类型实例(这里特指:1个指定实体的类型实例)</typeparam>

    /// <summary>

    /// 【仓储--接口】

    /// <remarks>

    /// 摘要:

    ///     通过继承于该接口的具体实现类中的泛型方法成员实例,为CURD操作提供方法支撑。

    /// </remarks>

    /// </summary>

    public interface IRepository<TEntity> where TEntity : BaseEntity

    {

        #region 属性--接口实现

        /// <summary>

        /// 【表】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定实体的可查询接口(IQueryable)1个指定实例,该实例中存储着1个指定实体的所有实例。

        /// 说明:

        ///     1IQueryable继承于IEnumerable。在此之上,增加了一些属性和扩展方法。但是,关键不在这些属性和方法上,而是Queryable实现了革命性的新行为特性。

        ///     2IQueryable革命性的特性是且有"延迟加载(lazy loading)特性,可查询接口(IQueryable)1个指定实例在内存中没有任何的实例数据,只调用该实例的ToList/ToListAsync方法才能把实例数据加载的内存中。

        /// </remarks>

        /// </summary>

        IQueryable<TEntity> Table { get; }

        #endregion

        #region 方法

        /// <param name="getAllAsync">1个具有返回值的泛型异步委托方法实例,该泛型异步委托方法实例用于获取1个指定实体的所有实例。</param>

        /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于获取缓存键类的1个指定实例。</param>

        /// <summary>

        /// 【异步获取实体】

        /// <remarks>

        /// 摘要:

        ///     直接从指定表中1个指定实体的所有实例;或从分布式缓存数据库获取1个指定实体的所有实例。

        /// </remarks>

        /// </summary>

        Task<IList<TEntity>> GetEntitiesAsync(Func<Task<IList<TEntity>>> getAllAsync, Func<IStaticCacheManager, CacheKey> getCacheKey);

        /// <param name="func">1个具有返回值的泛型委托方法实例,该泛型委托方法实例用于获取1个指定实体的1/n个实例。</param>

        /// <param name="pageIndex">当前页的页数值(“pageSize”结合,设定需要跳过指定实体实例的个数值),默认值:0,即不跳过。</param>

        /// <param name="pageSize">分页操作中每页最多显示实例的项()数值(“pageIndex”结合,设定需要跳过指定实体实例的个数值),默认值:int.MaxValue,即跳过int.MaxValue行数。 </param>

        /// <summary>

        /// 【异步分页列表】

        /// <remarks>

        /// 摘要:

        ///     以异步操作方式,只从数据源中加载指定1逻辑(内存)页中的数据,存储到“IPagedList”的实例中,从而尽量少的从指定表加载数据,从而尽量降低内存的消耗。

        ///  说明:

        ///     该方法没有定义缓存操作,更没有定义缓存的移除操作。

        /// </remarks>

        /// <returns>

        ///    “IPagedList”的实例,该实例存储着数据源中(符合指定查询条件的)所有实例。

        /// </returns>

        /// </summary>

        Task<IPagedList<TEntity>> GetAllPagedAsync(Func<IQueryable<TEntity>, IQueryable<TEntity>> func = null, int pageIndex = 0, int pageSize = int.MaxValue);

        /// <param name="func">1个具有返回值的泛型委托方法实例,该泛型异步委托方法实例用于获取1个指定实体的1/n个实例。</param>

        /// <param name="pageIndex">当前页的页数值(“pageSize”结合,设定需要跳过指定实体实例的个数值),默认值:0,即不跳过。</param>

        /// <param name="pageSize">分页操作中每页最多显示实例的项()数值(“pageIndex”结合,设定需要跳过指定实体实例的个数值),默认值:int.MaxValue,即跳过int.MaxValue行数。 </param>

        /// <summary>

        /// 【异步分页列表】

        /// <remarks>

        /// 摘要:

        ///     以异步操作方式,只从数据源中加载指定1逻辑(内存)页中的数据,存储到“IPagedList”的实例中,从而尽量少的从指定表加载数据,从而尽量降低内存的消耗。

        ///  说明:

        ///     该方法没有定义缓存操作,更没有定义缓存的移除操作。

        /// </remarks>

        /// <returns>

        ///    “IPagedList”的实例,该实例存储着数据源中(符合指定查询条件的)所有实例。

        /// </returns>

        /// </summary>

        Task<IPagedList<TEntity>> GetAllPagedAsync(Func<IQueryable<TEntity>, Task<IQueryable<TEntity>>> func = null, int pageIndex = 0, int pageSize = int.MaxValue);

        /// <param name="id">1个指定的长整型编号值。</param>

        /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于获取缓存键类的1个指定实例,默认值:null,即不存在缓存键实例。</param>

        /// <param name="includeDeleted">指示是否包含处于逻辑删除状态的实例,默认值:true,即包含。</param>

        /// <summary>

        /// 【异步通过编号值获取】

        /// <remarks>

        /// 摘要:

        ///     直接从指定表中1个指定实体的1个指定实例;或从分布式缓存数据库获取1个指定实体的1个指定实例(即使该实例处于逻辑删除状态,也获取该实例)

        /// </remarks>

        /// </summary>

        Task<TEntity> GetByIdAsync(long? id, Func<IStaticCacheManager, CacheKey> getCacheKey = null, bool includeDeleted = true);

        /// <param name="ids">列表接口实例,该实例存储着1/n个指定的长整型编号值。</param>

        /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于获取缓存键类的1个指定实例,默认值:null,即不存在缓存键实例。</param>

        /// <param name="includeDeleted">指示是否包含处于逻辑删除状态的实例,默认值:true,即包含。</param>

        /// <summary>

        /// 【异步通过编号值集获取】

        /// <remarks>

        /// 摘要:

        ///     直接从指定表中1个指定实体的1/n个指定实例;或从分布式缓存数据库获取1个指定实体的1/n个指定实例(即使该实例处于逻辑删除状态,也获取该实例)

        /// </remarks>

        /// </summary>

        Task<IList<TEntity>> GetByIdsAsync(IList<long> ids, Func<IStaticCacheManager, CacheKey> getCacheKey = null, bool includeDeleted = true);

        /// <param name="entity">指定实体的1个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化插入操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步插入】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1个指定实例持久化插入到指定表中后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        Task InsertAsync(TEntity entity, bool publishEvent = true);

        /// <param name="entity">指定实体的1个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步更新】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1个指定实例持久化更新到指定表中后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        Task UpdateAsync(TEntity entity, bool publishEvent = true);

        /// <param name=" entities">列表实例,该实例存储着指定实体的1/n个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步更新】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1/n个指定实例持久化更新到指定表中后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        Task UpdateAsync(IList<TEntity> entities, bool publishEvent = true);

        /// <param name="entity">指定实体的1个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步删除】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1个指定实例从指定表中物理删除后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        Task DeleteAsync(TEntity entity, bool publishEvent = true);

        /// <param name="entities">列表实例,该实例存储着指定实体的1/n个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步删除】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1/n个指定实例从指定表中物理删除后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

       Task DeleteAsync(IList<TEntity> entities, bool publishEvent = true);

        /// <param name="query">>“IQueryable”实例进行存储的1个指定类型的数据源(枚举数接口实例=长串型,包含:数组、列表、字典等)。。</param>

        /// <param name="includeDeleted">指示是否包含指定实体中所有的逻辑删除项。</param>

        /// <summary>

        /// 【逻辑删除过滤】

        /// <remarks>

        /// 摘要:

        ///     获取指定实体中所有的非逻辑删除实例。

        /// 说明:

        ///     1、由于政策因素,一些数据不能进行物理删除,只能进行逻辑删除,但以要在数据加载时,只加载非逻辑删除实例,达到减少内存消耗目标。

        ///     2、逻辑删除实例只具有数据纪录作用,而在渲染显示时已经无任何的意义,所以必须对处于逻辑删除状态的实例进行过滤。

        /// </remarks>

        /// </summary>

        IQueryable<TEntity> LogicDeletedFilter(IQueryable<TEntity> query, in bool includeDeleted);

        #endregion

    }

}

2 Data.Repository<TEntity>

using Core;

using Core.Caching;

using Core.Domain;

using Core.Events;

using Data.Extensions;

using Microsoft.EntityFrameworkCore;

namespace Data

{

    ///<typeparam name="TEntity">泛型类型实例(这里特指:1个指定实体的类型实例)</typeparam>

    /// <summary>

    /// 【仓储--类】

    /// <remarks>

    /// 摘要:

    ///     通过该类中的泛型方法成员实例,为CURD操作提供方法支撑。

    /// </remarks>

    /// </summary>

    public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity

    {

        #region 变量--私有/保护

        private readonly EFCoreContext _context;

        private readonly IStaticCacheManager _staticCacheManager;

        private readonly IEventPublisher _eventPublisher;

        #endregion

        #region 拷贝构造方法

        /// <param name="context">EFCore上下文类的1个指定实例 </param>

        /// <param name="staticCacheManager">分布式缓存接口实例。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过拷贝构造方法,对当前类中的同名变量成员进行实例化。

        /// </remarks>

        /// </summary>

        public Repository(

            EFCoreContext context,

            IStaticCacheManager staticCacheManager,

            IEventPublisher eventPublisher)

        {

            _context = context;

            _staticCacheManager = staticCacheManager;

            _eventPublisher = eventPublisher;

        }

        #endregion

        #region 属性--接口实现

        /// <summary>

        /// 【表】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定实体的可查询接口(IQueryable)1个指定实例,该实例中存储着1个指定实体的所有实例。

        /// 说明:

        ///     1IQueryable继承于IEnumerable。在此之上,增加了一些属性和扩展方法。但是,关键不在这些属性和方法上,而是Queryable实现了革命性的新行为特性。

        ///     2IQueryable革命性的特性是且有"延迟加载(lazy loading)特性,可查询接口(IQueryable)1个指定实例在内存中没有任何的实例数据,只调用该实例的ToList/ToListAsync方法才能把实例数据加载的内存中。

        /// </remarks>

        /// </summary>

        public IQueryable<TEntity> Table => _context.GetDbSet<TEntity>().AsQueryable();

        #endregion

        #region 方法--接口实现

        /// <param name="getAllAsync">1个具有返回值的泛型异步委托方法实例,该泛型异步委托方法实例用于获取1个指定实体的所有实例。</param>

        /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于获取缓存键类的1个指定实例。</param>

        /// <summary>

        /// 【异步获取实体】

        /// <remarks>

        /// 摘要:

        ///     直接从指定表中1个指定实体的所有实例;或从分布式缓存数据库获取1个指定实体的所有实例。

        /// </remarks>

        /// </summary>

        public async Task<IList<TEntity>> GetEntitiesAsync(Func<Task<IList<TEntity>>> getAllAsync, Func<IStaticCacheManager, CacheKey> getCacheKey)

        {

            //如果不存在缓存键实例,则直接从持久化表中获取1个指定实体的所有实例。

            if (getCacheKey == null)

                return await getAllAsync();

            //如果存在缓存键实例,则从分布式缓存数据库获取1个指定实体的所有实例。

            var cacheKey = getCacheKey(_staticCacheManager)

                           ?? _staticCacheManager.PrepareKeyForDefaultCache(EntityCacheDefaults<TEntity>.AllCacheKey);

            return await _staticCacheManager.GetAsync(cacheKey, getAllAsync);

        }

        /// <param name="func">1个具有返回值的泛型委托方法实例,该泛型委托方法实例用于获取1个指定实体的1/n个实例。</param>

        /// <param name="pageIndex">当前页的页数值(“pageSize”结合,设定需要跳过指定实体实例的个数值),默认值:0,即不跳过。</param>

        /// <param name="pageSize">分页操作中每页最多显示实例的项()数值(“pageIndex”结合,设定需要跳过指定实体实例的个数值),默认值:int.MaxValue,即跳过int.MaxValue行数。 </param>

        /// <summary>

        /// 【异步分页列表】

        /// <remarks>

        /// 摘要:

        ///     以异步操作方式,只从数据源中加载指定1逻辑(内存)页中的数据,存储到“IPagedList”的实例中,从而尽量少的从指定表加载数据,从而尽量降低内存的消耗。

        ///  说明:

        ///     该方法没有定义缓存操作,更没有定义缓存的移除操作。

        /// </remarks>

        /// <returns>

        ///    “IPagedList”的实例,该实例存储着数据源中(符合指定查询条件的)所有实例。

        /// </returns>

        /// </summary>

        public async Task<IPagedList<TEntity>> GetAllPagedAsync(Func<IQueryable<TEntity>, IQueryable<TEntity>> func = null, int pageIndex = 0, int pageSize = int.MaxValue)

        {

            var query = Table;

            query = func != null ? func(query) : query;

            return await query.ToPagedListAsync(pageIndex, pageSize);

        }

        /// <param name="func">1个具有返回值的泛型委托方法实例,该泛型异步委托方法实例用于获取1个指定实体的1/n个实例。</param>

        /// <param name="pageIndex">当前页的页数值(“pageSize”结合,设定需要跳过指定实体实例的个数值),默认值:0,即不跳过。</param>

        /// <param name="pageSize">分页操作中每页最多显示实例的项()数值(“pageIndex”结合,设定需要跳过指定实体实例的个数值),默认值:int.MaxValue,即跳过int.MaxValue行数。 </param>

        /// <summary>

        /// 【异步分页列表】

        /// <remarks>

        /// 摘要:

        ///     以异步操作方式,只从数据源中加载指定1逻辑(内存)页中的数据,存储到“IPagedList”的实例中,从而尽量少的从指定表加载数据,从而尽量降低内存的消耗。

        ///  说明:

        ///     该方法没有定义缓存操作,更没有定义缓存的移除操作。

        /// </remarks>

        /// <returns>

        ///    “IPagedList”的实例,该实例存储着数据源中(符合指定查询条件的)所有实例。

        /// </returns>

        /// </summary>

        public async Task<IPagedList<TEntity>> GetAllPagedAsync(Func<IQueryable<TEntity>, Task<IQueryable<TEntity>>> func = null, int pageIndex = 0, int pageSize = int.MaxValue)

        {

            var query = Table;

            query = func != null ? await func(query) : query;

            return await query.ToPagedListAsync(pageIndex, pageSize);

        }

        /// <param name="id">1个指定的长整型编号值。</param>

        /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于获取缓存键类的1个指定实例,默认值:null,即不存在缓存键实例。</param>

        /// <param name="includeDeleted">指示是否包含处于逻辑删除状态的实例,默认值:true,即包含。</param>

        /// <summary>

        /// 【异步通过编号值获取】

        /// <remarks>

        /// 摘要:

        ///     直接从指定表中1个指定实体的1个指定实例;或从分布式缓存数据库获取1个指定实体的1个指定实例(即使该实例处于逻辑删除状态,也获取该实例)

        /// </remarks>

        /// </summary>

        public async Task<TEntity> GetByIdAsync(long? id, Func<IStaticCacheManager, CacheKey> getCacheKey = null, bool includeDeleted = true)

        {

            //如果1个指定的长整型编号值,没有值;或该编号值为:0,则直接退出当前方法。

            if (!id.HasValue || id == 0)

                return null;

            // 通过异步委托方法,从指定表中获取1个指定实体的1个指定实例。

            async Task<TEntity> getEntityAsync()

            {

                return await Table.FirstOrDefaultAsync(entity => entity.Id == Convert.ToInt64(id));

            }

            //如果不存在缓存键实例,则直接返回1个指定实体的1个指定实例。

            if (getCacheKey == null)

                return await getEntityAsync();

            //如果存在缓存键实例,则把1个指定实体的1个指定实例,缓存到分布式缓存数据库中。

            var cacheKey = getCacheKey(_staticCacheManager)

                ?? _staticCacheManager.PrepareKeyForDefaultCache(EntityCacheDefaults<TEntity>.ByIdCacheKey, id);

            //从分布式缓存数据库返回1个指定实体的1个指定实例。

            return await _staticCacheManager.GetAsync(cacheKey, getEntityAsync);

        }

        /// <param name="ids">列表接口实例,该实例存储着1/n个指定的长整型编号值。</param>

        /// <param name="getCacheKey">1个具有返回值的委托方法实例,委托方法实例用于获取缓存键类的1个指定实例,默认值:null,即不存在缓存键实例。</param>

        /// <param name="includeDeleted">指示是否包含处于逻辑删除状态的实例,默认值:true,即包含。</param>

        /// <summary>

        /// 【异步通过编号值集获取】

        /// <remarks>

        /// 摘要:

        ///     直接从指定表中1个指定实体的1/n个指定实例;或从分布式缓存数据库获取1个指定实体的1/n个指定实例(即使该实例处于逻辑删除状态,也获取该实例)

        /// </remarks>

        /// </summary>

        public async Task<IList<TEntity>> GetByIdsAsync(IList<long> ids, Func<IStaticCacheManager, CacheKey> getCacheKey = null, bool includeDeleted = true)

        {

            //如果长整型列表实例中没有值,或该列表实例为:null,则直接退出当前方法。

            if (!ids?.Any() ?? true)

                return new List<TEntity>();

            // 通过异步委托方法,从指定表中获取1个指定实体的1/n个指定实例。

            async Task<IList<TEntity>> getByIdsAsync()

            {

                // 从指定表中获取1个指定实体的所有实例。

                var entries = await Table.Where(entry => ids!.Contains(entry.Id)).ToListAsync();

                //依次从所有实例中,获取与指定编号值相等的实例,并把这些实例存储到列表实例中。

                var sortedEntries = new List<TEntity>();

                foreach (var id in ids!)

                {

                    var sortedEntry = entries.Find(entry => entry.Id == id);

                    if (sortedEntry != null)

                        sortedEntries.Add(sortedEntry);

                }

                return sortedEntries;

            }

            //如果不存在缓存键实例,则直接返回1个指定实体的1/n个指定实例。

            if (getCacheKey == null)

                return await getByIdsAsync();

            //如果存在缓存键实例,则把1个指定实体的1/n个指定实例,缓存到分布式缓存数据库中。

            var cacheKey = getCacheKey(_staticCacheManager)

                ?? _staticCacheManager.PrepareKeyForDefaultCache(EntityCacheDefaults<TEntity>.ByIdsCacheKey, ids);

            //从分布式缓存数据库返回1个指定实体的1/n个指定实例。

            return await _staticCacheManager.GetAsync(cacheKey, getByIdsAsync);

        }

        /// <param name="entity">指定实体的1个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化插入操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步插入】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1个指定实例持久化插入到指定表中后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        public async Task InsertAsync(TEntity entity, bool publishEvent = true)

        {

            if (entity == null)

                throw new ArgumentNullException(nameof(entity));

            await _context.GetDbSet<TEntity>().AddAsync(entity);

            await _context.SaveChangesAsync();

            //在插入操作执行后,从分布式缓存数据为中强制移除指定体相关的所有缓存项。

            if (publishEvent)

                await _eventPublisher.EntityInsertedAsync(entity);

        }

        /// <param name="entity">指定实体的1个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步更新】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1个指定实例持久化更新到指定表中后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        public async Task UpdateAsync(TEntity entity, bool publishEvent = true)

        {

            if (entity == null)

                throw new ArgumentNullException(nameof(entity));

            _context.GetDbSet<TEntity>().Update(entity);

            await _context.SaveChangesAsync();

            //在更新操作执行后,从分布式缓存数据为中强制移除指定体相关的所有缓存项。

            if (publishEvent)

                await _eventPublisher.EntityUpdatedAsync(entity);

        }

        /// <param name=" entities">列表实例,该实例存储着指定实体的1/n个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步更新】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1/n个指定实例持久化更新到指定表中后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        public async Task UpdateAsync(IList<TEntity> entities, bool publishEvent = true)

        {

            if (entities == null)

                throw new ArgumentNullException(nameof(entities));

            if (entities.Count == 0)

                return;

            _context.GetDbSet<TEntity>().UpdateRange(entities);

            await _context.SaveChangesAsync();

            //如果不存在触发器实例,则直接退出当前方法。

            if (!publishEvent)

                return;

            //如果存在触发器实例,从分布式缓存数据为中强制移除指定体相关的所有缓存项。

            foreach (var entity in entities)

                await _eventPublisher.EntityUpdatedAsync(entity);

        }

        /// <param name="entity">指定实体的1个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步删除】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1个指定实例从指定表中物理删除后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        public async Task DeleteAsync(TEntity entity, bool publishEvent = true)

        {

            _context.GetDbSet<TEntity>().Remove(entity);

            await _context.SaveChangesAsync();

            //在物理删除操作执行后,从分布式缓存数据为中强制移除指定体相关的所有缓存项。

            if (publishEvent)

                await _eventPublisher.EntityDeletedAsync(entity);

        }

        /// <param name="entities">列表实例,该实例存储着指定实体的1/n个指定实例。</param>

        /// <param name="publishEvent">指示在指定实体的1个指定实例持久化更新操作成功后,是否从缓存数据库中移除与该实体相关的缓存项,默认值:true,即从缓存数据库中移除与该实体相关的缓存项。</param>

        /// <summary>

        /// 【异步删除】

        /// <remarks>

        /// 摘要:

        ///     把指定实体的1/n个指定实例从指定表中物理删除后,并从缓存数据库中移除与该实体相关的缓存项。

        /// </remarks>

        /// </summary>

        public async Task DeleteAsync(IList<TEntity> entities, bool publishEvent = true)

        {

            if (entities == null)

                throw new ArgumentNullException(nameof(entities));

            _context.GetDbSet<TEntity>().RemoveRange(entities);

            await _context.SaveChangesAsync();

            //如果不存在触发器实例,则直接退出当前方法。

            if (!publishEvent)

                return;

            //如果存在触发器实例,从分布式缓存数据为中强制移除指定体相关的所有缓存项。

            foreach (var entity in entities)

                await _eventPublisher.EntityDeletedAsync(entity);

        }

        /// <param name="query">>“IQueryable”实例进行存储的1个指定类型的数据源(枚举数接口实例=长串型,包含:数组、列表、字典等)。。</param>

        /// <param name="includeDeleted">指示是否包含指定实体中所有的逻辑删除项。</param>

        /// <summary>

        /// 【逻辑删除过滤】

        /// <remarks>

        /// 摘要:

        ///     获取指定实体中所有的非逻辑删除实例。

        /// 说明:

        ///     1、由于政策因素,一些数据不能进行物理删除,只能进行逻辑删除,但以要在数据加载时,只加载非逻辑删除实例,达到减少内存消耗目标。

        ///     2、逻辑删除实例只具有数据纪录作用,而在渲染显示时已经无任何的意义,所以必须对处于逻辑删除状态的实例进行过滤。

        /// </remarks>

        /// </summary>

        public IQueryable<TEntity> LogicDeletedFilter(IQueryable<TEntity> query, in bool includeDeleted)

        {

            if (includeDeleted)

                return query;

            if (typeof(TEntity).GetInterface(nameof(ILogicDeletedEntity)) == null)

                return query;

            return query.OfType<ILogicDeletedEntity>().Where(entry => !entry.Deleted).OfType<TEntity>();

        }

        #endregion

    }

}

3 重构Framework.Infrastructure.DbStartup.ConfigureServices

  //CURD操作实现的泛型类的实例,注入到.Net(Core)内置容器中。

            services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

4 WebApi.Controllers.EventPublisherTestController

using Core;

using Core.Caching;

using Core.Domain.Users;

using Core.Extensions;

using Data;

using Data.Extensions;

using Microsoft.AspNetCore.Mvc;

using Microsoft.EntityFrameworkCore;

using Newtonsoft.Json;

using System.Linq.Expressions;

using WebApi.Models;

namespace WebApi.Controllers

{

    [Route("[controller]/[action]")]

    [ApiController]

    public class RepositoryTestController : ControllerBase

    {

        #region 拷贝构造方法与变量

        private readonly IRepository<Role> _roleRepository;

        private readonly IRepository<User> _userRepository;

        private readonly IStaticCacheManager _staticCacheManager;

        public RepositoryTestController(IRepository<Role> roleRepository,

           IRepository<User> userRepository,

            IStaticCacheManager staticCacheManager)

        {

            _roleRepository = roleRepository;

            _userRepository = userRepository;

            _staticCacheManager = staticCacheManager;

        }

        #endregion

        [HttpGet]

        public async Task<MessageModel<List<Role>>> Table()

        {

            List<Role> _roleList = await _roleRepository.Table.ToListAsync();

            MessageModel<List<Role>> _messageModel = new MessageModel<List<Role>>();

            if (_roleList.Count > 0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "成功获取角色实体的所有实例!";

                _messageModel.Response = _roleList.ToList();

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "获取角色实体的所有实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpGet]

        public async Task<MessageModel<List<Role>>> GetEntitiesTestOfCacheAsync()

        {

            IList<Role> _roleList = await _roleRepository.GetEntitiesAsync(async () =>

                {

                    return await _roleRepository.Table.ToListAsync();

                },

                cache => _staticCacheManager.PrepareKeyForShortTermCache(EntityCacheDefaults<Role>.AllCacheKey));

            MessageModel<List<Role>> _messageModel = new MessageModel<List<Role>>();

           

            if (_roleList.Count>0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "成功获取角色实体的所有实例!";

                _messageModel.Response = _roleList.ToList();

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "获取角色实体的所有实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpPost]

        public async Task<MessageModel<PageModel<Role>>> PostRolePageByFromBodyAsync([FromBody] PaginationModel pagination)

        {

            //根据筛选字符串,为角色实例组合筛选lambda”表达式实例。

            Expression<Func<Role, bool>> _expression = null;

            if (!string.IsNullOrEmpty(pagination.QueryCondition))

            {

                _expression = ExpressionExtension.True<Role>();

                Role _role = JsonConvert.DeserializeAnonymousType(pagination.QueryCondition, new Role());

                if (_role!.Id > 0)

                {

                    _expression = _expression.And(p => p.Id == _role!.Id);

                }

                if (!string.IsNullOrEmpty(_role!.Name))

                {

                    _expression = _expression.And(p => p.Name.Contains(_role!.Name));

                }

                if (pagination.QueryCondition.Contains("IsActive", StringComparison.InvariantCultureIgnoreCase))

                {

                    _expression = _expression.And(p => p.IsActive == _role!.IsActive);

                }

                if (!string.IsNullOrEmpty(_role!.Remark))

                {

                    _expression = _expression.And(p => p.Remark.Contains(_role!.Remark));

                }

            }

            //IQueryable<Role> _roleQueryable = _context.GetDbSet<Role>().AsQueryable();

            IQueryable<Role> _roleQueryable = _roleRepository.Table;

            //获取所有符合条件的角色实例。

            if (_expression != null)

            {

                _roleQueryable = _roleQueryable.Where(_expression);

            }

            //把所有符合条件的角色实例,按照指定字段进行排序操作。

            if (!string.IsNullOrEmpty(pagination.OrderByFiled))

            {

                var _obj = JsonConvert.DeserializeAnonymousType(pagination.OrderByFiled, new

                {

                    Filed = "",

                    Type = "",

                });

                if (_obj!.Type == null)

                {

                    _roleQueryable = _roleQueryable.OrderByDescending(r => r.Id);

                }

                else if (_obj.Type!.Equals("ascending", StringComparison.InvariantCultureIgnoreCase))

                {

                    _roleQueryable = _roleQueryable.OrderBy(_obj!.Filed);

                }

                else if (_obj.Type!.Equals("descending", StringComparison.InvariantCultureIgnoreCase))

                {

                    _roleQueryable = _roleQueryable.OrderByDescending(_obj!.Filed);

                }

            }

            else

            {

                _roleQueryable = _roleQueryable.OrderBy(r => r.Id);

            }

            //根据前端页面传递的参数,从角色表中获取(1逻辑页中的)相应行数的数据,并把这些数据存储到列表实例中。

            IPagedList<Role> _roleSinglePageList = await _roleQueryable.ToPagedListAsync((pagination.PageIndex - 1), pagination.PageSize);

            //实例化当前模型页(“物理页”),为当前页面的渲染显示提供数据支撑。

            PageModel<Role> _rolePageModel = new PageModel<Role>()

            {

                PageIndex = pagination.PageIndex,

                PageSize = pagination.PageSize,

                TotalCount = _roleQueryable.LongCount(),

                Data = _roleSinglePageList,

            };

            //实例化消息模型录,对当前“Api”控制器行方法的执行操作结果进行存储,为客户端页面的渲染提供数据支撑。

            MessageModel<PageModel<Role>> _roleMessageModel = new MessageModel<PageModel<Role>>()

            {

                Success = true,

                Message = "获取成功",

                Response = _rolePageModel,

            };

            return _roleMessageModel;

        }

        [HttpGet]

        public async Task<MessageModel<Role>> GetByIdTestOfCacheAsync()

        {

            Role _role = await _roleRepository.GetByIdAsync(1, cache => default);

            MessageModel<Role> _messageModel = new MessageModel<Role>();

            if (_role != null)

            {

                _messageModel.Success = true;

                _messageModel.Message = "成功获取角色实体的所有实例!";

                _messageModel.Response = _role;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "获取角色实体的所有实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpGet]

        public async Task<MessageModel<List<Role>>> GetByIdsTestOfCacheAsync()

        {

            IList<Role> _roleList = await _roleRepository.GetByIdsAsync(new List<long> { 2, 3 }, cache => default);

            MessageModel<List<Role>> _messageModel = new MessageModel<List<Role>>();

            if (_roleList.Count > 0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "成功获取角色实体的所有实例!";

                _messageModel.Response = _roleList.ToList();

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "获取角色实体的所有实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpGet]

        public async Task<MessageModel<List<Role>>> GetEntitiesTestNoCacheAsync()

        {

            IList<Role> _roleList = await _roleRepository.GetEntitiesAsync(async () =>

            {

                return await _roleRepository.Table.ToListAsync();

            }, null);

            MessageModel<List<Role>> _messageModel = new MessageModel<List<Role>>();

            if (_roleList.Count > 0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "成功获取角色实体的所有实例!";

                _messageModel.Response = _roleList.ToList();

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "获取角色实体的所有实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpPost]

        public async Task<MessageModel<Role>> PostAddRoleAsync([FromBody] Role role)

        {

            await _roleRepository.InsertAsync(role);

            MessageModel<Role> _messageModel = new MessageModel<Role>();

            if (role != null)

            {

                _messageModel.Success = true;

                _messageModel.Message = "已经成功插入角色实体的1个指定实例!";

                _messageModel.Response = role;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "成功插入角色实体的1个指定实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpGet]

        public async Task<MessageModel<Role>> UpdateTestAsync()

        {

            Role _role = await _roleRepository.GetByIdAsync(1, null);

            _role.Name = _role.Name + "_Update";

            _role.Remark = _role.Remark + "_Update";

            await _roleRepository.UpdateAsync(_role);

            MessageModel<Role> _messageModel = new MessageModel<Role>();

            if (_role != null)

            {

                _messageModel.Success = true;

                _messageModel.Message = "已经成功更新角色实体的1个指定实例!";

                _messageModel.Response = _role;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "成功插入更新实体的1个指定实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpGet]

        public async Task<MessageModel<List<Role>>> UpdatesTestAsync()

        {

            IList<Role> _roleList = await _roleRepository.GetByIdsAsync(new List<long> { 2, 3 }, null);

            List<Role>  _list = new List<Role>();

            foreach (Role _role in _roleList)

            {

                _role.Name = _role.Name + "_Update_s";

                _role.Remark = _role.Remark + "_Update_s";

                _list.Add(_role);

            }

            await _roleRepository.UpdateAsync(_list);

            MessageModel<List<Role>> _messageModel = new MessageModel<List<Role>>();

            if (_roleList.Count > 0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "已经成功更新角色实体的1/n个指定实例!";

                _messageModel.Response = _list;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "成功插入更新实体的1/n个指定实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

        [HttpDelete]

        public async Task<MessageModel<bool>> DeleteTestAsync()

        {

            Role _role = await _roleRepository.GetByIdAsync(1, cache => default);

            await _roleRepository.DeleteAsync(_role);

            MessageModel<bool> _messageModel = new MessageModel<bool>();

            if (_role != null)

            {

                _messageModel.Success = true;

                _messageModel.Message = "已经成功物理删除角色实体的1个指定实例!";

                _messageModel.Response = true;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "成功插入物理删除实体的1个指定实例失败!";

                _messageModel.Response = false;

            }

            return _messageModel;

        }

        [HttpDelete]

        public async Task<MessageModel<bool>> DeletesTestAsync()

        {

            IList<Role> _roleList = await _roleRepository.GetByIdsAsync(new List<long> { 2, 3 }, cache => default);

            await _roleRepository.DeleteAsync(_roleList);

            MessageModel<bool> _messageModel = new MessageModel<bool>();

            if (_roleList.Count > 0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "已经成功物理删除角色实体的1/n个指定实例!";

                _messageModel.Response = true;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "成功插入物理删除实体的1/n个指定实例失败!";

                _messageModel.Response = false;

            }

            return _messageModel;

        }

        [HttpGet]

        public async Task<MessageModel<List<User>>> LogicDeletedFilterTest()

        {

            List<User> _userList = await _userRepository.LogicDeletedFilter(_userRepository.Table,false).ToListAsync();

            MessageModel<List<User>> _messageModel = new MessageModel<List<User>>();

            if (_userList.Count > 0)

            {

                _messageModel.Success = true;

                _messageModel.Message = "成功获取用户实体中所有的非逻辑删除实例!";

                _messageModel.Response = _userList;

            }

            else

            {

                _messageModel.Status = 500;

                _messageModel.Success = false;

                _messageModel.Message = "获取用户实体中所有的非逻辑删除实例失败!";

                _messageModel.Response = null;

            }

            return _messageModel;

        }

    }

}

对以上功能更为具体实现和注释见:230204_025shopDemo(CURD操作的泛型定义实现之IRepository)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值