Selaa lähdekoodia

迁移至.NET Core 2.2

懒得勤快 6 vuotta sitten
vanhempi
sitoutus
d78bb44abb
100 muutettua tiedostoa jossa 4361 lisäystä ja 17188 poistoa
  1. 3 0
      src/.gitignore
  2. 0 29
      src/BLL/App.config
  3. 0 136
      src/BLL/BLL.csproj
  4. 0 2941
      src/BLL/BaseBLL.cs
  5. 0 48
      src/BLL/Blls.cs
  6. 0 26
      src/BLL/Blls.tt
  7. 0 36
      src/BLL/CommentBll.cs
  8. 0 33
      src/BLL/LeaveMessageBll.cs
  9. 0 20
      src/BLL/MenuBll.cs
  10. 0 36
      src/BLL/Properties/AssemblyInfo.cs
  11. 0 17
      src/BLL/packages.config
  12. 0 20
      src/Common/AggregatedCounter.cs
  13. 0 30
      src/Common/App.config
  14. 0 175
      src/Common/AsposeLicense.cs
  15. 0 16
      src/Common/Assemblies.cs
  16. 0 106
      src/Common/Common.csproj
  17. 0 36
      src/Common/Properties/AssemblyInfo.cs
  18. 0 15
      src/Common/packages.config
  19. 0 25
      src/DAL/App.config
  20. 0 3169
      src/DAL/BaseDal.cs
  21. 0 130
      src/DAL/DAL.csproj
  22. 0 28
      src/DAL/Dals.cs
  23. 0 24
      src/DAL/Dals.tt
  24. 0 36
      src/DAL/Properties/AssemblyInfo.cs
  25. 0 21
      src/DAL/packages.config
  26. 0 44
      src/Factory/Factory.cs
  27. 0 45
      src/Factory/Factory.csproj
  28. 0 81
      src/Factory/ObjectPool.cs
  29. 0 36
      src/Factory/Properties/AssemblyInfo.cs
  30. 0 29
      src/IBLL/App.config
  31. 0 87
      src/IBLL/IBLL.csproj
  32. 0 2246
      src/IBLL/IBaseBll.cs
  33. 0 2220
      src/IBLL/IBaseBll.tt
  34. 0 16
      src/IBLL/IMenuBll.cs
  35. 0 36
      src/IBLL/Properties/AssemblyInfo.cs
  36. 0 5
      src/IBLL/packages.config
  37. 0 70
      src/IBLL/readme.txt
  38. 0 29
      src/IDAL/App.config
  39. 0 2133
      src/IDAL/IBaseDal.cs
  40. 0 2104
      src/IDAL/IBaseDal.tt
  41. 0 77
      src/IDAL/IDAL.csproj
  42. 0 36
      src/IDAL/Properties/AssemblyInfo.cs
  43. 0 5
      src/IDAL/packages.config
  44. 0 70
      src/IDAL/readme.txt
  45. 37 0
      src/Masuit.MyBlogs.Core.sln
  46. 0 0
      src/Masuit.MyBlogs.Core/App_Data/DenyIPRange.txt
  47. 0 0
      src/Masuit.MyBlogs.Core/App_Data/ban.txt
  48. 0 0
      src/Masuit.MyBlogs.Core/App_Data/denyareaip.txt
  49. 0 0
      src/Masuit.MyBlogs.Core/App_Data/denyip.txt
  50. 0 0
      src/Masuit.MyBlogs.Core/App_Data/mod.txt
  51. 0 0
      src/Masuit.MyBlogs.Core/App_Data/whitelist.txt
  52. 22 44
      src/Masuit.MyBlogs.Core/Common/CommonHelper.cs
  53. 3 3
      src/Masuit.MyBlogs.Core/Common/DocumentConvert.cs
  54. 1 1
      src/Masuit.MyBlogs.Core/Common/HangfireHelper.cs
  55. 5 4
      src/Masuit.MyBlogs.Core/Common/RegisterAutomapper.cs
  56. 9 0
      src/Masuit.MyBlogs.Core/Configs/AppConfig.cs
  57. 38 0
      src/Masuit.MyBlogs.Core/Configs/HangfireJobInit.cs
  58. 120 0
      src/Masuit.MyBlogs.Core/Configs/RegisterAutomapper.cs
  59. 11 26
      src/Masuit.MyBlogs.Core/Controllers/AdminController.cs
  60. 59 51
      src/Masuit.MyBlogs.Core/Controllers/BaseController.cs
  61. 181 0
      src/Masuit.MyBlogs.Core/Controllers/BugController.cs
  62. 98 0
      src/Masuit.MyBlogs.Core/Controllers/CategoryController.cs
  63. 340 0
      src/Masuit.MyBlogs.Core/Controllers/CommentController.cs
  64. 77 0
      src/Masuit.MyBlogs.Core/Controllers/ContactController.cs
  65. 141 0
      src/Masuit.MyBlogs.Core/Controllers/DashboardController.cs
  66. 91 0
      src/Masuit.MyBlogs.Core/Controllers/DonateController.cs
  67. 18 6
      src/Masuit.MyBlogs.Core/Controllers/ErrorController.cs
  68. 91 44
      src/Masuit.MyBlogs.Core/Controllers/FileController.cs
  69. 6 5
      src/Masuit.MyBlogs.Core/Controllers/HealthController.cs
  70. 94 64
      src/Masuit.MyBlogs.Core/Controllers/HomeController.cs
  71. 102 27
      src/Masuit.MyBlogs.Core/Controllers/LinksController.cs
  72. 102 0
      src/Masuit.MyBlogs.Core/Controllers/MenuController.cs
  73. 95 25
      src/Masuit.MyBlogs.Core/Controllers/MiscController.cs
  74. 349 0
      src/Masuit.MyBlogs.Core/Controllers/MsgController.cs
  75. 207 0
      src/Masuit.MyBlogs.Core/Controllers/NoticeController.cs
  76. 204 0
      src/Masuit.MyBlogs.Core/Controllers/PassportController.cs
  77. 350 149
      src/Masuit.MyBlogs.Core/Controllers/PostController.cs
  78. 38 33
      src/Masuit.MyBlogs.Core/Controllers/PublicController.cs
  79. 59 27
      src/Masuit.MyBlogs.Core/Controllers/SearchController.cs
  80. 223 0
      src/Masuit.MyBlogs.Core/Controllers/SeminarController.cs
  81. 68 0
      src/Masuit.MyBlogs.Core/Controllers/ShareController.cs
  82. 317 0
      src/Masuit.MyBlogs.Core/Controllers/SubscribeController.cs
  83. 131 34
      src/Masuit.MyBlogs.Core/Controllers/SystemController.cs
  84. 50 26
      src/Masuit.MyBlogs.Core/Controllers/ToolsController.cs
  85. 69 39
      src/Masuit.MyBlogs.Core/Controllers/UploadController.cs
  86. 87 0
      src/Masuit.MyBlogs.Core/Controllers/UserController.cs
  87. 28 23
      src/Masuit.MyBlogs.Core/Extensions/AuthorityAttribute.cs
  88. 72 0
      src/Masuit.MyBlogs.Core/Extensions/ExceptionMiddleware.cs
  89. 84 0
      src/Masuit.MyBlogs.Core/Extensions/FirewallMiddleware.cs
  90. 159 0
      src/Masuit.MyBlogs.Core/Extensions/Hangfire/HangfireBackJob.cs
  91. 15 0
      src/Masuit.MyBlogs.Core/Extensions/Hangfire/IHangfireBackJob.cs
  92. 1 1
      src/Masuit.MyBlogs.Core/Extensions/Hangfire/IpIntercepter.cs
  93. 16 0
      src/Masuit.MyBlogs.Core/Extensions/IApplicationBuilderExtensions.cs
  94. 3 2
      src/Masuit.MyBlogs.Core/Extensions/LuceneHelper.cs
  95. 27 0
      src/Masuit.MyBlogs.Core/Extensions/UEditor/ConfigHandler.cs
  96. 10 12
      src/Masuit.MyBlogs.Core/Extensions/UEditor/CrawlerHandler.cs
  97. 33 0
      src/Masuit.MyBlogs.Core/Extensions/UEditor/Handler.cs
  98. 12 15
      src/Masuit.MyBlogs.Core/Extensions/UEditor/ListFileManager.cs
  99. 4 4
      src/Masuit.MyBlogs.Core/Extensions/UEditor/NotSupportedHandler.cs
  100. 1 1
      src/Masuit.MyBlogs.Core/Extensions/UEditor/PathFormatter.cs

+ 3 - 0
src/.gitignore

@@ -0,0 +1,3 @@
+bin
+obj
+/Masuit.MyBlogs.Core/Masuit.MyBlogs.Core.csproj.user

+ 0 - 29
src/BLL/App.config

@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <configSections>
-    
-    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
-  <entityFramework>
-    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
-      <parameters>
-        <parameter value="mssqllocaldb" />
-      </parameters>
-    </defaultConnectionFactory>
-    <providers>
-      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
-    </providers>
-  </entityFramework>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.1.0" newVersion="7.0.1.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration>

+ 0 - 136
src/BLL/BLL.csproj

@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{F7DEF70A-7EEA-4C03-866B-E351B352711C}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>BLL</RootNamespace>
-    <AssemblyName>BLL</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="AngleSharp, Version=0.9.9.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
-      <HintPath>..\packages\AngleSharp.0.9.11\lib\net45\AngleSharp.dll</HintPath>
-    </Reference>
-    <Reference Include="AutoMapper, Version=8.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
-      <HintPath>..\packages\AutoMapper.8.0.0\lib\net461\AutoMapper.dll</HintPath>
-    </Reference>
-    <Reference Include="EFSecondLevelCache, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\EFSecondLevelCache.1.2.0.0\lib\net45\EFSecondLevelCache.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="HtmlSanitizer, Version=3.0.0.0, Culture=neutral, PublicKeyToken=61c49a1a9e79cc28, processorArchitecture=MSIL">
-      <HintPath>..\packages\HtmlSanitizer.4.0.204\lib\net45\HtmlSanitizer.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.SharpZipLib, Version=1.1.0.145, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
-      <HintPath>..\packages\SharpZipLib.1.1.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="Microsoft.VisualBasic" />
-    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="NinjaNye.SearchExtensions, Version=2.2.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\NinjaNye.SearchExtensions.2.2.0\lib\net45\NinjaNye.SearchExtensions.dll</HintPath>
-    </Reference>
-    <Reference Include="PanGu.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\PanGu.Core.1.0.0\lib\net451\PanGu.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="PanGu.HighLight, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\PanGu.HighLight.1.0.0\lib\net451\PanGu.HighLight.dll</HintPath>
-    </Reference>
-    <Reference Include="StackExchange.Redis, Version=1.2.6.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\StackExchange.Redis.1.2.6\lib\net46\StackExchange.Redis.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.DataAnnotations" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.IO.Compression" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Xml.Serialization" />
-    <Reference Include="System.Xml.XmlSerializer" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="BaseBLL.cs" />
-    <Compile Include="Blls.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Blls.tt</DependentUpon>
-    </Compile>
-    <Compile Include="CategoryBll.cs" />
-    <Compile Include="CommentBll.cs" />
-    <Compile Include="LeaveMessageBll.cs" />
-    <Compile Include="MenuBll.cs" />
-    <Compile Include="PostBll.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="UserInfoBll.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\Masuit.Tools\Masuit.Tools\Masuit.Tools.csproj">
-      <Project>{275d5a0d-c49c-497e-a4b5-f40285c2495f}</Project>
-      <Name>Masuit.Tools</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Common\Common.csproj">
-      <Project>{138F01FA-B23F-4ACA-93DB-D899BB244A1A}</Project>
-      <Name>Common</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\IBLL\IBLL.csproj">
-      <Project>{939493b4-a47c-43e2-99e3-92459cd0eb1e}</Project>
-      <Name>IBLL</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\IDAL\IDAL.csproj">
-      <Project>{7997FB01-C9C1-4793-A430-9CA3C3852B37}</Project>
-      <Name>IDAL</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Models\Models.csproj">
-      <Project>{5400CA01-CBCF-4531-A388-3057393D5B4F}</Project>
-      <Name>Models</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Blls.tt">
-      <Generator>TextTemplatingFileGenerator</Generator>
-      <LastGenOutput>Blls.cs</LastGenOutput>
-    </Content>
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 2941
src/BLL/BaseBLL.cs

@@ -1,2941 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data.Entity.Infrastructure;
-using System.Data.SqlClient;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
-using EFSecondLevelCache;
-using IBLL;
-using IDAL;
-
-namespace BLL
-{
-    /// <summary>
-    /// 业务层基类
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class BaseBll<T> : IBaseBll<T> where T : class, new()
-    {
-        public virtual IBaseDal<T> BaseDal { get; set; }// = Factory.CreateInstance<IBaseDal<T>>("DAL." + typeof(T).Name + "Dal");
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> GetAll()
-        {
-            return BaseDal.GetAll();
-        }
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> GetAllNoTracking()
-        {
-            return BaseDal.GetAllNoTracking();
-        }
-
-        /// <summary>
-        /// 从一级缓存获取所有实体
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCache(int timespan = 20)
-        {
-            return BaseDal.GetAllFromCache(timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCacheNoTracking(int timespan = 20)
-        {
-            return BaseDal.GetAllFromCacheNoTracking(timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync(int timespan = 20)
-        {
-            return await BaseDal.GetAllFromCacheNoTrackingAsync(timespan);
-        }
-
-        /// <summary>
-        /// 从一级缓存获取所有实体(异步)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheAsync(int timespan = 20)
-        {
-            return await BaseDal.GetAllFromCacheAsync(timespan);
-        }
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual EFCachedQueryable<T> GetAllFromL2Cache()
-        {
-            return BaseDal.GetAllFromL2Cache();
-        }
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual EFCachedQueryable<T> GetAllFromL2CacheNoTracking()
-        {
-            return BaseDal.GetAllFromL2CacheNoTracking();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAll<TDto>()
-        {
-            return BaseDal.GetAll<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAllNoTracking<TDto>()
-        {
-            return BaseDal.GetAllNoTracking<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCache<TDto>(int timespan = 20) where TDto : class
-        {
-            return BaseDal.GetAllFromCache<TDto>(timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheAsync<TDto>(int timespan = 20) where TDto : class
-        {
-            return await BaseDal.GetAllFromCacheAsync<TDto>(timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCacheNoTracking<TDto>(int timespan = 20) where TDto : class
-        {
-            return BaseDal.GetAllFromCacheNoTracking<TDto>(timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TDto>(int timespan = 20) where TDto : class
-        {
-            return await BaseDal.GetAllFromCacheNoTrackingAsync<TDto>(timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2Cache<TDto>()
-        {
-            return BaseDal.GetAllFromL2Cache<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2CacheNoTracking<TDto>()
-        {
-            return BaseDal.GetAllFromL2CacheNoTracking<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAll(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllNoTracking(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetAll(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetAllNoTracking(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return BaseDal.GetAllFromCache(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllFromCache(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return await BaseDal.GetAllFromCacheAsync(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllFromCacheAsync(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return BaseDal.GetAllFromCacheNoTracking(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllFromCacheNoTracking(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return await BaseDal.GetAllFromCacheNoTrackingAsync(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllFromCacheNoTrackingAsync(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetAllFromL2Cache(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllFromL2Cache(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetAllFromL2CacheNoTracking(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllFromL2CacheNoTracking(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetAll<TS, TDto>(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAll<TS, TDto>(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetAllNoTracking<TS, TDto>(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.GetAllNoTracking<TS, TDto>(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return BaseDal.GetAllFromCache<TS, TDto>(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.GetAllFromCache<TS, TDto>(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return await BaseDal.GetAllFromCacheAsync<TS, TDto>(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.GetAllFromCacheAsync<TS, TDto>(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return BaseDal.GetAllFromCacheNoTracking<TS, TDto>(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.GetAllFromCacheNoTracking<TS, TDto>(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return await BaseDal.GetAllFromCacheNoTrackingAsync<TS, TDto>(orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.GetAllFromCacheNoTrackingAsync<TS, TDto>(orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class
-        {
-            return BaseDal.GetAllFromL2Cache<TS, TDto>(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.GetAllFromL2Cache<TS, TDto>(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class
-        {
-            return BaseDal.GetAllFromL2CacheNoTracking<TS, TDto>(orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.GetAllFromL2CacheNoTracking<TS, TDto>(orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadEntities(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntities(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> IBaseBll<T>.LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc)
-        {
-            return null;
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntities(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntities(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntities<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntities<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        public virtual IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntities<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        public IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntities<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCache(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return BaseDal.LoadEntitiesFromCache(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return BaseDal.LoadEntitiesFromCache(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        public IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromCache(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCache<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCache<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCache<TS, TDto>(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2Cache(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntitiesFromL2Cache(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntitiesFromL2Cache(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2Cache(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2Cache<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntitiesFromL2Cache<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntitiesFromL2Cache<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2Cache<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesAsync(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesAsync(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesAsync<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return await BaseDal.LoadEntitiesFromCacheAsync(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return await BaseDal.LoadEntitiesFromCacheAsync(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromCacheAsync(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.LoadEntitiesFromCacheAsync<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.LoadEntitiesFromCacheAsync<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCacheAsync<TS, TDto>(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheAsync(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheAsync(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheAsync<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadEntitiesNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntitiesNoTracking(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntitiesNoTracking(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesNoTracking(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntitiesNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntitiesNoTracking<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntitiesNoTracking<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesNoTracking<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTracking(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTracking(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTracking(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTracking<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTracking<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTracking<TS, TDto>(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2CacheNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTracking(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTracking(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTracking(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTracking<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTracking<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTracking<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesNoTrackingAsync(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesNoTrackingAsync(@where, @orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesNoTrackingAsync(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesNoTrackingAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesNoTrackingAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesNoTrackingAsync<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return await BaseDal.LoadEntitiesFromCacheNoTrackingAsync(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return await BaseDal.LoadEntitiesFromCacheNoTrackingAsync(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTrackingAsync(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.LoadEntitiesFromCacheNoTrackingAsync<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheNoTrackingAsync(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheNoTrackingAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTrackingAsync(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntity(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntity(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntity<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntity(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntity<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntity<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntity<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntity<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromCache(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return BaseDal.GetFirstEntityFromCache(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual T GetFirstEntityFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return BaseDal.GetFirstEntityFromCache(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return BaseDal.GetFirstEntityFromCache<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return BaseDal.GetFirstEntityFromCache<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromL2Cache(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntityFromL2Cache(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual T GetFirstEntityFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntityFromL2Cache(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromL2Cache<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntityFromL2Cache<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntityFromL2Cache<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return await BaseDal.GetFirstEntityFromCacheAsync(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return await BaseDal.GetFirstEntityFromCacheAsync(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.GetFirstEntityFromCacheAsync<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.GetFirstEntityFromCacheAsync<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheAsync(where);
-        }
-
-        /// <summary>
-        ///  获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityAsync(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntityNoTracking(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntityNoTracking(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntityNoTracking<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntityNoTracking<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return BaseDal.GetFirstEntityFromCacheNoTracking(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return BaseDal.GetFirstEntityFromCacheNoTracking(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return BaseDal.GetFirstEntityFromCacheNoTracking<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return BaseDal.GetFirstEntityFromCacheNoTracking<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromL2CacheNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntityFromL2CacheNoTracking(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntityFromL2CacheNoTracking(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.GetFirstEntityFromL2CacheNoTracking<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.GetFirstEntityFromL2CacheNoTracking<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityNoTrackingAsync(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityNoTrackingAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityNoTrackingAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityNoTrackingAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return await BaseDal.GetFirstEntityFromCacheNoTrackingAsync(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return await BaseDal.GetFirstEntityFromCacheNoTrackingAsync(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.GetFirstEntityFromCacheNoTrackingAsync<TDto>(where, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return await BaseDal.GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheNoTrackingAsync(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheNoTrackingAsync(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await BaseDal.GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 根据ID找实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        public virtual T GetById(object id)
-        {
-            return BaseDal.GetById(id);
-        }
-
-        /// <summary>
-        /// 根据ID找实体(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetByIdAsync(object id)
-        {
-            return await BaseDal.GetByIdAsync(id);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby,
-            bool isAsc = true)
-        {
-            return BaseDal.LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc)
-        {
-            return BaseDal.LoadPageEntities<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntities<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return BaseDal.LoadPageEntitiesFromCache(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesFromCache(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, int timespan = 30) where TDto : class
-        {
-            return BaseDal.LoadPageEntitiesFromCache<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.LoadPageEntitiesFromCache<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadPageEntitiesFromL2Cache(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesFromL2Cache(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc)
-        {
-            return BaseDal.LoadPageEntitiesFromL2Cache<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesFromL2Cache<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadPageEntitiesNoTracking<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesNoTracking<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return BaseDal.LoadPageEntitiesFromCacheNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesFromCacheNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return BaseDal.LoadPageEntitiesFromCacheNoTracking<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return BaseDal.LoadPageEntitiesFromCacheNoTracking<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, timespan, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadPageEntitiesFromL2CacheNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesFromL2CacheNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return BaseDal.LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return BaseDal.LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby);
-        }
-
-        /// <summary>
-        /// 根据ID删除实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteById(object id)
-        {
-            return BaseDal.DeleteById(id);
-        }
-
-        /// <summary>
-        /// 根据ID删除实体并保存
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteByIdSaved(object id)
-        {
-            BaseDal.DeleteById(id);
-            return SaveChanges() > 0;
-        }
-
-        /// <summary>
-        /// 根据ID删除实体并保存(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        public virtual async Task<int> DeleteByIdSavedAsync(object id)
-        {
-            BaseDal.DeleteById(id);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 删除实体并保存
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteEntity(T t)
-        {
-            return BaseDal.DeleteEntity(t);
-        }
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        public virtual int DeleteEntity(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.DeleteEntity(where);
-        }
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        public virtual int DeleteEntitySaved(Expression<Func<T, bool>> @where)
-        {
-            BaseDal.DeleteEntity(where);
-            return SaveChanges();
-        }
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        public virtual async Task<int> DeleteEntitySavedAsync(Expression<Func<T, bool>> @where)
-        {
-            BaseDal.DeleteEntity(where);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 根据条件删除实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        public virtual async Task<int> DeleteEntityAsync(Expression<Func<T, bool>> @where)
-        {
-            return await BaseDal.DeleteEntityAsync(where);
-        }
-
-        /// <summary>
-        /// 删除实体并保存
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteEntitySaved(T t)
-        {
-            BaseDal.DeleteEntity(t);
-            return SaveChanges() > 0;
-        }
-
-        /// <summary>
-        /// 删除实体并保存(异步)
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        public virtual async Task<int> DeleteEntitySavedAsync(T t)
-        {
-            BaseDal.DeleteEntity(t);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 更新实体
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual bool UpdateEntity(T t)
-        {
-            return BaseDal.UpdateEntity(t);
-        }
-
-        /// <summary>
-        /// 更新实体并保存
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual bool UpdateEntitySaved(T t)
-        {
-            BaseDal.UpdateEntity(t);
-            return SaveChanges() > 0;
-        }
-
-        /// <summary>
-        /// 更新实体并保存(异步)
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual async Task<int> UpdateEntitySavedAsync(T t)
-        {
-            BaseDal.UpdateEntity(t);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 根据条件更新实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual int UpdateEntity(Expression<Func<T, bool>> @where, T t)
-        {
-            return BaseDal.UpdateEntity(where, t);
-        }
-
-        /// <summary>
-        /// 根据条件更新实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual async Task<int> UpdateEntityAsync(Expression<Func<T, bool>> @where, T t)
-        {
-            return await BaseDal.UpdateEntityAsync(where, t);
-        }
-
-        /// <summary>
-        /// 添加实体
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        public virtual T AddEntity(T t)
-        {
-            return BaseDal.AddEntity(t);
-        }
-
-        /// <summary>
-        /// 添加实体并保存
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        public virtual T AddEntitySaved(T t)
-        {
-            T entity = BaseDal.AddEntity(t);
-            bool b = SaveChanges() > 0;
-            return b ? entity : null;
-        }
-
-        /// <summary>
-        /// 添加实体并保存(异步)
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        public virtual async Task<int> AddEntitySavedAsync(T t)
-        {
-            BaseDal.AddEntity(t);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 添加或更新
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        public virtual void AddOrUpdate(Expression<Func<T, object>> exp, params T[] entities)
-        {
-            BaseDal.AddOrUpdate(exp, entities);
-        }
-
-        /// <summary>
-        /// 添加或更新并保存
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        public virtual int AddOrUpdateSaved(Expression<Func<T, object>> exp, params T[] entities)
-        {
-            AddOrUpdate(exp, entities);
-            return SaveChanges();
-        }
-
-        /// <summary>
-        /// 添加或更新并保存(异步)
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        public virtual async Task<int> AddOrUpdateSavedAsync(Expression<Func<T, object>> exp, params T[] entities)
-        {
-            AddOrUpdate(exp, entities);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 统一保存的方法
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        public virtual int SaveChanges()
-        {
-            return BaseDal.SaveChanges();
-        }
-
-        /// <summary>
-        /// 统一保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        public virtual async Task<int> SaveChangesAsync()
-        {
-            return await BaseDal.SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 判断实体是否在数据库中存在
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        public virtual bool Any(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.Any(where);
-        }
-
-        /// <summary>
-        /// 统计符合条件的个数
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns></returns>
-        public int Count(Expression<Func<T, bool>> @where)
-        {
-            return BaseDal.Count(where);
-        }
-
-        /// <summary>
-        /// 删除多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteEntities(IEnumerable<T> list)
-        {
-            return BaseDal.DeleteEntities(list);
-        }
-
-        /// <summary>
-        /// 删除多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteEntitiesSaved(IEnumerable<T> list)
-        {
-            BaseDal.DeleteEntities(list);
-            return SaveChanges() > 0;
-        }
-
-        /// <summary>
-        /// 删除多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        public virtual async Task<int> DeleteEntitiesSavedAsync(IEnumerable<T> list)
-        {
-            BaseDal.DeleteEntities(list);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 更新多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        public virtual bool UpdateEntities(IEnumerable<T> list)
-        {
-            return BaseDal.UpdateEntities(list);
-        }
-
-        /// <summary>
-        /// 更新多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        public virtual bool UpdateEntitiesSaved(IEnumerable<T> list)
-        {
-            BaseDal.UpdateEntities(list);
-            return SaveChanges() > 0;
-        }
-
-        /// <summary>
-        /// 更新多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        public virtual async Task<int> UpdateEntitiesSavedAsync(IEnumerable<T> list)
-        {
-            BaseDal.UpdateEntities(list);
-            return await SaveChangesAsync();
-        }
-
-        /// <summary>
-        /// 添加多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        public virtual IEnumerable<T> AddEntities(IList<T> list)
-        {
-            IEnumerable<T> entities = BaseDal.AddEntities(list);
-            SaveChanges();
-            return entities;
-        }
-
-        /// <summary>
-        /// 添加多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        public virtual async Task<IEnumerable<T>> AddEntitiesAsync(IList<T> list)
-        {
-            IEnumerable<T> entities = BaseDal.AddEntities(list);
-            await SaveChangesAsync();
-            return entities;
-        }
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        /// <returns>泛型集合</returns>
-        public virtual DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters)
-        {
-            return BaseDal.SqlQuery<TS>(sql, parameters);
-        }
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        public virtual DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters)
-        {
-            return BaseDal.SqlQuery(t, sql, parameters);
-        }
-
-        /// <summary>
-        /// 执行DML语句
-        /// </summary>
-        /// <param name="sql"></param>
-        /// <param name="parameters"></param>
-        public virtual void ExecuteSql(string sql, params SqlParameter[] parameters)
-        {
-            BaseDal.ExecuteSql(sql, parameters);
-        }
-
-        /// <summary>
-        /// 批量添加实体
-        /// </summary>
-        /// <param name="list">需要添加的实体</param>
-        public virtual void BulkInsert(IEnumerable<T> list)
-        {
-            BaseDal.BulkInsert(list);
-        }
-
-        /// <summary>
-        /// 统一批量保存数据
-        /// </summary>
-        public virtual void BulkSaveChanges()
-        {
-            BaseDal.BulkSaveChanges();
-        }
-    }
-}

+ 0 - 48
src/BLL/Blls.cs

@@ -1,48 +0,0 @@
-
-using IBLL;
-using Models.Entity;
-namespace BLL
-{
-	
-	public partial class BroadcastBll :BaseBll<Broadcast>,IBroadcastBll{}   
-	
-	public partial class CategoryBll :BaseBll<Category>,ICategoryBll{}   
-	
-	public partial class CommentBll :BaseBll<Comment>,ICommentBll{}   
-	
-	public partial class ContactsBll :BaseBll<Contacts>,IContactsBll{}   
-	
-	public partial class DonateBll :BaseBll<Donate>,IDonateBll{}   
-	
-	public partial class FastShareBll :BaseBll<FastShare>,IFastShareBll{}   
-	
-	public partial class InternalMessageBll :BaseBll<InternalMessage>,IInternalMessageBll{}   
-	
-	public partial class IssueBll :BaseBll<Issue>,IIssueBll{}   
-	
-	public partial class LeaveMessageBll :BaseBll<LeaveMessage>,ILeaveMessageBll{}   
-	
-	public partial class LinksBll :BaseBll<Links>,ILinksBll{}   
-	
-	public partial class LoginRecordBll :BaseBll<LoginRecord>,ILoginRecordBll{}   
-	
-	public partial class MenuBll :BaseBll<Menu>,IMenuBll{}   
-	
-	public partial class MiscBll :BaseBll<Misc>,IMiscBll{}   
-	
-	public partial class NoticeBll :BaseBll<Notice>,INoticeBll{}   
-	
-	public partial class PostBll :BaseBll<Post>,IPostBll{}   
-	
-	public partial class PostAccessRecordBll :BaseBll<PostAccessRecord>,IPostAccessRecordBll{}   
-	
-	public partial class PostHistoryVersionBll :BaseBll<PostHistoryVersion>,IPostHistoryVersionBll{}   
-	
-	public partial class SearchDetailsBll :BaseBll<SearchDetails>,ISearchDetailsBll{}   
-	
-	public partial class SeminarBll :BaseBll<Seminar>,ISeminarBll{}   
-	
-	public partial class SystemSettingBll :BaseBll<SystemSetting>,ISystemSettingBll{}   
-	
-	public partial class UserInfoBll :BaseBll<UserInfo>,IUserInfoBll{}   
-}

+ 0 - 26
src/BLL/Blls.tt

@@ -1,26 +0,0 @@
-<#@ template language="C#" debug="false" hostspecific="true"#>
-<#@ include file="EF.Utility.CS.ttinclude"#>
-<#@output extension=".cs"#>
-<#
-CodeGenerationTools code = new CodeGenerationTools(this);
-MetadataLoader loader = new MetadataLoader(this);
-CodeRegion region = new CodeRegion(this, 1);
-MetadataTools ef = new MetadataTools(this);
-
-string inputFile = @"..\\ModelCodeGenerate\\Model.edmx";//EF模型路径
-
-EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
-string namespaceName = code.VsNamespaceSuggestion();
-EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
-#>
-using IBLL;
-using Models.Entity;
-namespace BLL
-{
-<#
-foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
-{
-#>	
-	public partial class <#=entity.Name#>Bll :BaseBll<<#=entity.Name#>>,I<#=entity.Name#>Bll{}   
-<#}#>
-}

+ 0 - 36
src/BLL/CommentBll.cs

@@ -1,36 +0,0 @@
-using Masuit.Tools.Net;
-using Models.Application;
-using Models.Entity;
-using System.Data.Entity.Infrastructure;
-using System.Linq;
-
-namespace BLL
-{
-    public partial class CommentBll
-    {
-        /// <summary>
-        /// 通过存储过程获得自己以及自己所有的子元素集合
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public DbRawSqlQuery<Comment> GetSelfAndAllChildrenCommentsByParentId(int id)
-        {
-            return WebExtension.GetDbContext<DataContext>().Database.SqlQuery<Comment>("exec sp_getChildrenCommentByParentId " + id);
-        }
-
-        /// <summary>
-        /// 根据无级子级找顶级父级评论id
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public int GetParentCommentIdByChildId(int id)
-        {
-            DbRawSqlQuery<int> raw = WebExtension.GetDbContext<DataContext>().Database.SqlQuery<int>("exec sp_getParentCommentIdByChildId " + id);
-            if (raw.Any())
-            {
-                return raw.FirstOrDefault();
-            }
-            return 0;
-        }
-    }
-}

+ 0 - 33
src/BLL/LeaveMessageBll.cs

@@ -1,33 +0,0 @@
-using System.Data.Entity.Infrastructure;
-using System.Linq;
-using Masuit.Tools.Net;
-using Models.Application;
-using Models.Entity;
-
-namespace BLL
-{
-    public partial class LeaveMessageBll
-    {
-        /// <summary>
-        /// 通过存储过程获得自己以及自己所有的子元素集合
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public DbRawSqlQuery<LeaveMessage> GetSelfAndAllChildrenMessagesByParentId(int id) => WebExtension.GetDbContext<DataContext>().Database.SqlQuery<LeaveMessage>("exec sp_getChildrenLeaveMsgByParentId " + id);
-
-        /// <summary>
-        /// 根据无级子级找顶级父级留言id
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public int GetParentMessageIdByChildId(int id)
-        {
-            var raw = WebExtension.GetDbContext<DataContext>().Database.SqlQuery<int>("exec sp_getParentMessageIdByChildId " + id);
-            if (raw.Any())
-            {
-                return raw.FirstOrDefault();
-            }
-            return 0;
-        }
-    }
-}

+ 0 - 20
src/BLL/MenuBll.cs

@@ -1,20 +0,0 @@
-using System.Data.Entity.Infrastructure;
-using Masuit.Tools.Net;
-using Models.Application;
-using Models.Entity;
-
-namespace BLL
-{
-    public partial class MenuBll
-    {
-        /// <summary>
-        /// 通过存储过程获得自己以及自己所有的子元素集合
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public DbRawSqlQuery<Menu> GetChildrenMenusByParentId(int id)
-        {
-            return WebExtension.GetDbContext<DataContext>().Database.SqlQuery<Menu>("exec sp_getChildrenMenusByParentId " + id);
-        }
-    }
-}

+ 0 - 36
src/BLL/Properties/AssemblyInfo.cs

@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("BLL")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("BLL")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 会使此程序集中的类型
-//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("f7def70a-7eea-4c03-866b-e351b352711c")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 17
src/BLL/packages.config

@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="AngleSharp" version="0.9.11" targetFramework="net461" />
-  <package id="AutoMapper" version="8.0.0" targetFramework="net461" />
-  <package id="EFSecondLevelCache" version="1.2.0.0" targetFramework="net45" />
-  <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
-  <package id="EntityFramework.zh-Hans" version="6.2.0" targetFramework="net45" />
-  <package id="HtmlSanitizer" version="4.0.204" targetFramework="net461" />
-  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net461" />
-  <package id="NinjaNye.SearchExtensions" version="2.2.0" targetFramework="net461" />
-  <package id="PanGu.Core" version="1.0.0" targetFramework="net461" />
-  <package id="PanGu.HighLight" version="1.0.0" targetFramework="net461" />
-  <package id="SharpZipLib" version="1.1.0" targetFramework="net461" />
-  <package id="StackExchange.Redis" version="1.2.6" targetFramework="net46" />
-  <package id="System.Linq.Queryable" version="4.3.0" targetFramework="net461" />
-  <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />
-</packages>

+ 0 - 20
src/Common/AggregatedCounter.cs

@@ -1,20 +0,0 @@
-using Models.ViewModel;
-
-namespace Common
-{
-    /// <summary>
-    /// 访客统计缓存
-    /// </summary>
-    public class AggregatedCounter
-    {
-        /// <summary>
-        /// 独立访客统计汇总
-        /// </summary>
-        public static AnalysisModel UniqueInterviews { get; set; } = new AnalysisModel();
-
-        /// <summary>
-        /// 直接访客统计汇总
-        /// </summary>
-        public static AnalysisModel TotalInterviews { get; set; } = new AnalysisModel();
-    }
-}

+ 0 - 30
src/Common/App.config

@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <configSections>
-    
-    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
-  <entityFramework>
-    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
-      <parameters>
-        <parameter value="mssqllocaldb" />
-      </parameters>
-    </defaultConnectionFactory>
-    <providers>
-      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
-    </providers>
-  </entityFramework>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.1.0" newVersion="7.0.1.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>

+ 0 - 175
src/Common/AsposeLicense.cs

@@ -1,175 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Xml;
-
-namespace Common
-{
-    /// <summary>
-    /// Aspose内存补丁
-    /// </summary>
-    public static class AsposeLicense
-    {
-        private static readonly string AsposeList = "Aspose.3D.dll, Aspose.BarCode.dll, Aspose.BarCode.Compact.dll, Aspose.BarCode.WPF.dll, Aspose.Cells.GridDesktop.dll, Aspose.Cells.GridWeb.dll, Aspose.CAD.dll, Aspose.Cells.dll, Aspose.Diagram.dll, Aspose.Email.dll, Aspose.Imaging.dll, Aspose.Note.dll, Aspose.OCR.dll, Aspose.Pdf.dll, Aspose.Slides.dll, Aspose.Tasks.dll, Aspose.Words.dll";
-
-        /// <summary>
-        /// 启动Aspose的内存破解
-        /// </summary>
-        public static void ActivateMemoryPatching()
-        {
-            Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies();
-            foreach (Assembly assembly in arr)
-            {
-                if (AsposeList.IndexOf(assembly.FullName.Split(',')[0] + ".dll") != -1)
-                    ActivateForAssembly(assembly);
-            }
-            AppDomain.CurrentDomain.AssemblyLoad += ActivateOnLoad;
-        }
-
-        private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
-        {
-            if (AsposeList.IndexOf(e.LoadedAssembly.FullName.Split(',')[0] + ".dll") != -1)
-                ActivateForAssembly(e.LoadedAssembly);
-        }
-
-        private static void ActivateForAssembly(Assembly assembly)
-        {
-            MethodInfo miLicensed1 = typeof(AsposeLicense).GetMethod("InvokeMe1", BindingFlags.NonPublic | BindingFlags.Static);
-            MethodInfo miLicensed2 = typeof(AsposeLicense).GetMethod("InvokeMe2", BindingFlags.NonPublic | BindingFlags.Static);
-
-            Dictionary<string, MethodInfo> miDict = new Dictionary<string, MethodInfo>
-            {
-                ["System.DateTime"] = miLicensed1,
-                ["System.Xml.XmlElement"] = miLicensed2
-            };
-
-            Type[] arrType = null;
-            bool isFound = false;
-            int nCount = 0;
-
-            try
-            {
-                arrType = assembly.GetTypes();
-            }
-            catch (ReflectionTypeLoadException err)
-            {
-                arrType = err.Types;
-            }
-            foreach (Type type in arrType)
-            {
-                if (isFound) break;
-                if (type == null) continue;
-                MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
-                foreach (MethodInfo info in arrMInfo)
-                {
-                    if (isFound) break;
-                    try
-                    {
-                        string strMethod = info.ToString();
-                        if ((strMethod.IndexOf("(System.Xml.XmlElement, System.String)") > 0) && miDict.ContainsKey(info.ReturnType.ToString()))
-                        {
-                            var miEvaluation = info;
-                            MemoryPatching(miEvaluation, miDict[miEvaluation.ReturnType.ToString()]);
-                            nCount++;
-                            if (((assembly.FullName.IndexOf("Aspose.Pdf") == -1) && (nCount == 2)) || ((assembly.FullName.IndexOf("Aspose.Pdf") != -1) && (nCount == 6)))
-                            {
-                                isFound = true;
-                                break;
-                            }
-                        }
-                    }
-                    catch
-                    {
-                        throw new InvalidOperationException("MemoryPatching for \"" + assembly.FullName + "\" failed !");
-                    }
-                }
-            }
-
-            string[] aParts = assembly.FullName.Split(',');
-            string fName = aParts[0];
-            if (fName.IndexOf("Aspose.BarCode.") != -1)
-                fName = "Aspose.BarCode";
-            else if (fName.IndexOf("Aspose.3D") != -1)
-                fName = "Aspose.ThreeD";
-
-            try
-            {
-                Type type2 = assembly.GetType(fName + ".License");
-                MethodInfo mi = type2.GetMethod("SetLicense", new[] { typeof(Stream) });
-                const string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5MaWNlbnNlZTwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPmxpY2Vuc2VlQGVtYWlsLmNvbTwvRW1haWxUbz4KICAgIDxMaWNlbnNlVHlwZT5EZXZlbG9wZXIgT0VNPC9MaWNlbnNlVHlwZT4KICAgIDxMaWNlbnNlTm90ZT5MaW1pdGVkIHRvIDEwMDAgZGV2ZWxvcGVyLCB1bmxpbWl0ZWQgcGh5c2ljYWwgbG9jYXRpb25zPC9MaWNlbnNlTm90ZT4KICAgIDxPcmRlcklEPjc4NDM3ODU3Nzg1PC9PcmRlcklEPgogICAgPFVzZXJJRD4xMTk3ODkyNDM3OTwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIFByb2R1Y3QgRmFtaWx5PC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+e0YyQjk3MDQ1LTFCMjktNEIzRi1CRDUzLTYwMUVGRkExNUFBOX08L1NlcmlhbE51bWJlcj4KICAgIDxTdWJzY3JpcHRpb25FeHBpcnk+MjA5OTEyMzE8L1N1YnNjcmlwdGlvbkV4cGlyeT4KICAgIDxMaWNlbnNlVmVyc2lvbj4zLjA8L0xpY2Vuc2VWZXJzaW9uPgogIDwvRGF0YT4KICA8U2lnbmF0dXJlPlFYTndiM05sTGxSdmRHRnNJRkJ5YjJSMVkzUWdSbUZ0YVd4NTwvU2lnbmF0dXJlPgo8L0xpY2Vuc2U+";
-                Stream stream = new MemoryStream(Convert.FromBase64String(LData));
-                stream.Seek(0, SeekOrigin.Begin);
-                mi.Invoke(Activator.CreateInstance(type2, null), new[] { stream });
-            }
-            catch
-            {
-                throw new InvalidOperationException("SetLicense for \"" + assembly.FullName + "\" failed !");
-            }
-        }
-
-        private static DateTime InvokeMe1(XmlElement element, string name)
-        {
-            return DateTime.MaxValue;
-        }
-
-        private static XmlElement InvokeMe2(XmlElement element, string name)
-        {
-            if (element.LocalName == "License")
-            {
-                const string License64 = "PERhdGE+PExpY2Vuc2VkVG8+R3JvdXBEb2NzPC9MaWNlbnNlZFRvPjxMaWNlbnNlVHlwZT5TaXRlIE9FTTwvTGljZW5zZVR5cGU+PExpY2Vuc2VOb3RlPkxpbWl0ZWQgdG8gMTAgZGV2ZWxvcGVyczwvTGljZW5zZU5vdGU+PE9yZGVySUQ+MTMwNzI0MDQwODQ5PC9PcmRlcklEPjxPRU0+VGhpcyBpcyBhIHJlZGlzdHJpYnV0YWJsZSBsaWNlbnNlPC9PRU0+PFByb2R1Y3RzPjxQcm9kdWN0PkFzcG9zZS5Ub3RhbDwvUHJvZHVjdD48L1Byb2R1Y3RzPjxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT48U2VyaWFsTnVtYmVyPjliNTc5NTAxLTUyNjEtNDIyMC04NjcwLWZjMmQ4Y2NkZDkwYzwvU2VyaWFsTnVtYmVyPjxTdWJzY3JpcHRpb25FeHBpcnk+MjAxNDA3MjQ8L1N1YnNjcmlwdGlvbkV4cGlyeT48TGljZW5zZVZlcnNpb24+Mi4yPC9MaWNlbnNlVmVyc2lvbj48L0RhdGE+PFNpZ25hdHVyZT5udFpocmRoL3I0QS81ZFpsU2dWYnhac0hYSFBxSjZ5UVVYa0RvaW4vS2lVZWhUUWZET0lQdHdzUlR2NmRTUVplOVdXekNnV3RGdkdROWpmR2QySmF4YUQvbkx1ZEk2R0VVajhqeVhUMG4vbWRrMEF1WVZNYlBXRjJYd3dSTnFlTmRrblYyQjhrZVFwbDJ2RzZVbnhxS2J6VVFxS2Rhc1pzZ2w1Q0xqSFVEWms9PC9TaWduYXR1cmU+";
-                element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(License64));
-            }
-
-            if (element.LocalName == "BlackList")
-            {
-                const string BlackList64 = "PERhdGE+PC9EYXRhPjxTaWduYXR1cmU+cUJwMEx1cEVoM1ZnOWJjeS8vbUVXUk9KRWZmczRlY25iTHQxYlNhanU2NjY5RHlad09FakJ1eEdBdVBxS1hyd0x5bmZ5VWplYUNGQ0QxSkh2RVUxVUl5eXJOTnBSMXc2NXJIOUFyUCtFbE1lVCtIQkZ4NFMzckFVMnd6dkxPZnhGeU9DQ0dGQ2UraTdiSHlGQk44WHp6R1UwdGRPMGR1RTFoRTQ5M1RNY3pRPTwvU2lnbmF0dXJlPg==";
-                element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(BlackList64));
-            }
-
-            XmlNodeList elementsByTagName = element.GetElementsByTagName(name);
-            if (elementsByTagName.Count <= 0)
-                return null;
-
-            return (XmlElement)elementsByTagName[0];
-        }
-
-        private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
-        {
-            IntPtr intPtrEval = GetMemoryAddress(miEvaluation);
-            IntPtr intPtrLicensed = GetMemoryAddress(miLicensed);
-
-            if (IntPtr.Size == 8)
-                *(long*)intPtrEval.ToPointer() = *(long*)intPtrLicensed.ToPointer();
-            else
-                *(int*)intPtrEval.ToPointer() = *(int*)intPtrLicensed.ToPointer();
-        }
-
-        private static unsafe IntPtr GetMemoryAddress(MethodBase mb)
-        {
-            RuntimeHelpers.PrepareMethod(mb.MethodHandle);
-
-            if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053)))
-                return new IntPtr((int*)mb.MethodHandle.Value.ToPointer() + 2);
-
-            ulong* location = (ulong*)mb.MethodHandle.Value.ToPointer();
-            int index = (int)((*location >> 32) & 0xFF);
-            if (IntPtr.Size == 8)
-            {
-                ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer();
-                ulong* address = classStart + index + 10;
-                return new IntPtr(address);
-            }
-            else
-            {
-                uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
-                uint* address = classStart + index + 10;
-                return new IntPtr(address);
-            }
-        }
-    }
-}
-
-//End

+ 0 - 16
src/Common/Assemblies.cs

@@ -1,16 +0,0 @@
-using System;
-using System.Configuration;
-using System.IO;
-using System.Reflection;
-
-namespace Common
-{
-    /// <summary>
-    /// 程序集缓存
-    /// </summary>
-    public static class Assemblies
-    {
-        public static Assembly ServiceAssembly { get; set; } = Assembly.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", ConfigurationManager.AppSettings["BllPath"] ?? "BLL.dll"));
-        public static Assembly RepositoryAssembly { get; set; } = Assembly.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", ConfigurationManager.AppSettings["DalPath"] ?? "DAL.dll"));
-    }
-}

+ 0 - 106
src/Common/Common.csproj

@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{138F01FA-B23F-4ACA-93DB-D899BB244A1A}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Common</RootNamespace>
-    <AssemblyName>Common</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Aspose.Words, Version=18.11.0.0, Culture=neutral, PublicKeyToken=716fcc553a201e56, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\libs\Aspose.Words.dll</HintPath>
-    </Reference>
-    <Reference Include="AutoMapper, Version=8.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
-      <HintPath>..\packages\AutoMapper.8.0.0\lib\net461\AutoMapper.dll</HintPath>
-    </Reference>
-    <Reference Include="EFSecondLevelCache, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\EFSecondLevelCache.1.2.0.0\lib\net45\EFSecondLevelCache.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="Hangfire.Core, Version=1.6.21.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\Hangfire.Core.1.6.21\lib\net45\Hangfire.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Hangfire.SqlServer, Version=1.6.21.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\Hangfire.SqlServer.1.6.21\lib\net45\Hangfire.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="Microsoft.Owin, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\Microsoft.Owin.4.0.0\lib\net451\Microsoft.Owin.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Owin.Host.SystemWeb, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.4.0.0\lib\net451\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
-      <HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
-    </Reference>
-    <Reference Include="StackExchange.Redis, Version=1.2.6.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\StackExchange.Redis.1.2.6\lib\net46\StackExchange.Redis.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.IO.Compression" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="CommonHelper.cs" />
-    <Compile Include="DocumentConvert.cs" />
-    <Compile Include="HangfireHelper.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="RegisterAutomapper.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\Masuit.Tools\Masuit.Tools\Masuit.Tools.csproj">
-      <Project>{275d5a0d-c49c-497e-a4b5-f40285c2495f}</Project>
-      <Name>Masuit.Tools</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Models\Models.csproj">
-      <Project>{5400CA01-CBCF-4531-A388-3057393D5B4F}</Project>
-      <Name>Models</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 36
src/Common/Properties/AssemblyInfo.cs

@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("Common")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Common")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 会使此程序集中的类型
-//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("138f01fa-b23f-4aca-93db-d899bb244a1a")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 15
src/Common/packages.config

@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="AutoMapper" version="8.0.0" targetFramework="net461" />
-  <package id="EFSecondLevelCache" version="1.2.0.0" targetFramework="net45" />
-  <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
-  <package id="Hangfire" version="1.6.21" targetFramework="net46" />
-  <package id="Hangfire.Core" version="1.6.21" targetFramework="net46" />
-  <package id="Hangfire.SqlServer" version="1.6.21" targetFramework="net46" />
-  <package id="Microsoft.Owin" version="4.0.0" targetFramework="net46" />
-  <package id="Microsoft.Owin.Host.SystemWeb" version="4.0.0" targetFramework="net46" />
-  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net461" />
-  <package id="Owin" version="1.0" targetFramework="net45" />
-  <package id="StackExchange.Redis" version="1.2.6" targetFramework="net46" />
-  <package id="System.ValueTuple" version="4.5.0" targetFramework="net46" requireReinstallation="true" />
-</packages>

+ 0 - 25
src/DAL/App.config

@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <configSections>
-    
-    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
-  <entityFramework>
-    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
-      <parameters>
-        <parameter value="mssqllocaldb" />
-      </parameters>
-    </defaultConnectionFactory>
-    <providers>
-      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
-    </providers>
-  </entityFramework>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.1.0" newVersion="7.0.1.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration>

+ 0 - 3169
src/DAL/BaseDal.cs

@@ -1,3169 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data.Entity;
-using System.Data.Entity.Infrastructure;
-using System.Data.Entity.Migrations;
-using System.Data.SqlClient;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
-using AutoMapper;
-using EFSecondLevelCache;
-using EntityFramework.Caching;
-using EntityFramework.Extensions;
-using IDAL;
-using Masuit.Tools;
-using Masuit.Tools.Net;
-using Masuit.Tools.Systems;
-using Models.Application;
-
-namespace DAL
-{
-    /// <summary>
-    /// DAL基类
-    /// </summary>
-    /// <typeparam name="T">实体类型</typeparam>
-    public class BaseDal<T> : Disposable, IBaseDal<T> where T : class, new()
-    {
-        public virtual DataContext DataContext { get; set; } = WebExtension.GetDbContext<DataContext>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> GetAll()
-        {
-            return DataContext.Set<T>();
-        }
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> GetAllNoTracking()
-        {
-            return DataContext.Set<T>().AsNoTracking();
-        }
-
-        /// <summary>
-        /// 从一级缓存获取所有实体
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCache(int timespan = 20)
-        {
-            return DataContext.Set<T>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCacheNoTracking(int timespan = 20)
-        {
-            return DataContext.Set<T>().AsNoTracking().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync(int timespan = 20)
-        {
-            return await DataContext.Set<T>().AsNoTracking().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 从一级缓存获取所有实体(异步)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheAsync(int timespan = 20)
-        {
-            return await DataContext.Set<T>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual EFCachedQueryable<T> GetAllFromL2Cache()
-        {
-            return DataContext.Set<T>().Cacheable();
-        }
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual EFCachedQueryable<T> GetAllFromL2CacheNoTracking()
-        {
-            return DataContext.Set<T>().AsNoTracking().Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAll<TDto>()
-        {
-            return DataContext.Set<T>().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAllNoTracking<TDto>()
-        {
-            return DataContext.Set<T>().AsNoTracking().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCache<TDto>(int timespan = 20) where TDto : class
-        {
-            return DataContext.Set<T>().ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheAsync<TDto>(int timespan = 20) where TDto : class
-        {
-            return await DataContext.Set<T>().ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCacheNoTracking<TDto>(int timespan = 20) where TDto : class
-        {
-            return DataContext.Set<T>().AsNoTracking().ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TDto>(int timespan = 20) where TDto : class
-        {
-            return await DataContext.Set<T>().AsNoTracking().ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2Cache<TDto>()
-        {
-            return DataContext.Set<T>().ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2CacheNoTracking<TDto>()
-        {
-            return DataContext.Set<T>().AsNoTracking().ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().OrderBy(orderby) : DataContext.Set<T>().OrderByDescending(orderby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            IOrderedQueryable<T> query;
-            if (isAsc)
-            {
-                query = DataContext.Set<T>().OrderBy(@orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenBy(e);
-                    }
-                }
-            }
-            else
-            {
-                query = DataContext.Set<T>().OrderByDescending(@orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenByDescending(e);
-                    }
-                }
-            }
-            return query;
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().AsNoTracking().OrderBy(orderby) : DataContext.Set<T>().AsNoTracking().OrderByDescending(orderby);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            IOrderedQueryable<T> query;
-            if (isAsc)
-            {
-                query = DataContext.Set<T>().AsNoTracking().OrderBy(@orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenBy(e);
-                    }
-                }
-            }
-            else
-            {
-                query = DataContext.Set<T>().AsNoTracking().OrderByDescending(@orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenByDescending(e);
-                    }
-                }
-            }
-            return query;
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return GetAll(orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return GetAll(orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return await GetAll(orderby, isAsc).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await GetAll(orderby, isAsc, thenby).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return GetAllNoTracking(orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return GetAllNoTracking(orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20)
-        {
-            return await GetAllNoTracking(orderby, isAsc).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await GetAllNoTracking(orderby, isAsc, thenby).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return GetAll(orderby, isAsc).Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return GetAll(orderby, isAsc, thenby).Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return GetAllNoTracking(orderby, isAsc).Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return GetAllNoTracking(orderby, isAsc, thenby).Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return GetAll(orderby, isAsc).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return GetAll(orderby, isAsc, thenby).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return GetAllNoTracking(orderby, isAsc).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return GetAllNoTracking(orderby, isAsc, thenby).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return GetAll<TS, TDto>(orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return GetAll<TS, TDto>(orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return await GetAll<TS, TDto>(orderby, isAsc).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return await GetAll<TS, TDto>(orderby, isAsc, thenby).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return GetAllNoTracking<TS, TDto>(orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return GetAllNoTracking<TS, TDto>(orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class
-        {
-            return await GetAllNoTracking(orderby, isAsc).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return await GetAllNoTracking(orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class
-        {
-            return GetAll(orderby, isAsc).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return GetAll(orderby, isAsc, thenby).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class
-        {
-            return GetAllNoTracking(orderby, isAsc).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return GetAllNoTracking(orderby, isAsc, thenby).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadEntities(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().Where(@where).OrderBy(orderby) : DataContext.Set<T>().Where(@where).OrderByDescending(orderby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            IOrderedQueryable<T> query;
-            if (isAsc)
-            {
-                query = DataContext.Set<T>().Where(@where).OrderBy(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenBy(e);
-                    }
-                }
-            }
-            else
-            {
-                query = DataContext.Set<T>().Where(@where).OrderByDescending(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenByDescending(e);
-                    }
-                }
-            }
-            return query;
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntities<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        public virtual IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntities(where, orderby, isAsc).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        public virtual IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntities(where, orderby, isAsc, thenby).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCache(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return DataContext.Set<T>().Where(@where).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return LoadEntities(where, orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntities(where, orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return DataContext.Set<T>().Where(@where).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return LoadEntities(where, orderby, isAsc).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return LoadEntities(where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2Cache(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntities(where, orderby, isAsc).Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntities(where, orderby, isAsc, thenby).Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2Cache<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).Cacheable().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntities(where, orderby, isAsc).Cacheable().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntities(where, orderby, isAsc, thenby).Cacheable().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesAsync(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where)).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby) : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby)).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query;
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).ProjectToQueryable<TDto>()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).ProjectToQueryable<TDto>() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).ProjectToQueryable<TDto>()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query.ProjectToQueryable<TDto>();
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return await WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return await LoadEntities(where, orderby, isAsc).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await LoadEntities(where, orderby, isAsc, thenby).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return await DataContext.Set<T>().Where(@where).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return await LoadEntities(where, orderby, isAsc).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return await LoadEntities(where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).Cacheable() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query.Cacheable();
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).ProjectToQueryable<TDto>().Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).ProjectToQueryable<TDto>().Cacheable() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).ProjectToQueryable<TDto>().Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query.ProjectToQueryable<TDto>().Cacheable();
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadEntitiesNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).AsNoTracking();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().Where(@where).AsNoTracking().OrderBy(orderby) : DataContext.Set<T>().Where(@where).AsNoTracking().OrderByDescending(orderby);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            IOrderedQueryable<T> query;
-            if (isAsc)
-            {
-                query = DataContext.Set<T>().Where(@where).AsNoTracking().OrderBy(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenBy(e);
-                    }
-                }
-            }
-            else
-            {
-                query = DataContext.Set<T>().Where(@where).AsNoTracking().OrderByDescending(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenByDescending(e);
-                    }
-                }
-            }
-            return query;
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntitiesNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).AsNoTracking().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc, thenby).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return DataContext.Set<T>().Where(@where).AsNoTracking().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return DataContext.Set<T>().Where(@where).AsNoTracking().ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2CacheNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).AsNoTracking().Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc).Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc, thenby).Cacheable();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).AsNoTracking().Cacheable().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc).Cacheable().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadEntitiesNoTracking(where, orderby, isAsc, thenby).Cacheable().ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).AsNoTracking() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).AsNoTracking()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query;
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().ProjectToQueryable<TDto>()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).AsNoTracking().ProjectToQueryable<TDto>() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).AsNoTracking().ProjectToQueryable<TDto>()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query.ProjectToQueryable<TDto>();
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return await DataContext.Set<T>().Where(@where).AsNoTracking().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return await LoadEntitiesNoTracking(where, orderby, isAsc).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await LoadEntitiesNoTracking(where, orderby, isAsc, thenby).FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return await DataContext.Set<T>().Where(@where).AsNoTracking().ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return await LoadEntitiesNoTracking(where, orderby, isAsc).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return await LoadEntitiesNoTracking(where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCacheAsync(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan))).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).AsNoTracking().Cacheable() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).AsNoTracking().Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query.Cacheable();
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await Task.Run(() => WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().ProjectToQueryable<TDto>().Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return await Task.Run(() => isAsc ? WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderBy(orderby).AsNoTracking().ProjectToQueryable<TDto>().Cacheable() : WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).OrderByDescending(orderby).AsNoTracking().ProjectToQueryable<TDto>().Cacheable()).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual async Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return await Task.Run(() =>
-            {
-                IOrderedQueryable<T> query;
-                if (isAsc)
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderBy(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenBy(e);
-                        }
-                    }
-                }
-                else
-                {
-                    query = WebExtension.GetDbContext<DataContext>().Set<T>().Where(@where).AsNoTracking().OrderByDescending(@orderby);
-                    if (thenby.Length > 0)
-                    {
-                        foreach (var e in thenby)
-                        {
-                            query = query.ThenByDescending(e);
-                        }
-                    }
-                }
-                return query.ProjectToQueryable<TDto>().Cacheable();
-            }).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntity(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().FirstOrDefault(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntity<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().OrderBy(orderby).FirstOrDefault(where) : DataContext.Set<T>().OrderByDescending(orderby).FirstOrDefault(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntity<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(where).ProjectToFirstOrDefault<TDto>();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntity<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().Where(where).OrderBy(orderby).ProjectToFirstOrDefault<TDto>() : DataContext.Set<T>().Where(where).OrderByDescending(orderby).ProjectToFirstOrDefault<TDto>();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromCache(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return LoadEntitiesFromCache(where, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual T GetFirstEntityFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return LoadEntitiesFromCache(where, orderby, isAsc, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return LoadEntitiesFromCache<TDto>(where, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return LoadEntitiesFromCache<TS, TDto>(where, orderby, isAsc, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromL2Cache(Expression<Func<T, bool>> @where)
-        {
-            return LoadEntitiesFromL2Cache(where).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual T GetFirstEntityFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesFromL2Cache(where, orderby, isAsc).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromL2Cache<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return LoadEntitiesFromL2Cache<TDto>(where).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesFromL2Cache<TS, TDto>(where, orderby, isAsc).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityAsync(Expression<Func<T, bool>> @where)
-        {
-            return await DataContext.Set<T>().FirstOrDefaultAsync(where).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? await DataContext.Set<T>().OrderBy(orderby).FirstOrDefaultAsync(where).ConfigureAwait(true) : await DataContext.Set<T>().OrderByDescending(orderby).FirstOrDefaultAsync(where).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await DataContext.Set<T>().Where(where).ProjectToFirstOrDefaultAsync<TDto>().ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? await DataContext.Set<T>().Where(where).OrderBy(orderby).ProjectToFirstOrDefaultAsync<TDto>().ConfigureAwait(true) : await DataContext.Set<T>().Where(where).OrderByDescending(orderby).ProjectToFirstOrDefaultAsync<TDto>().ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            var list = await LoadEntitiesFromCacheAsync(@where, timespan).ConfigureAwait(true);
-            return list.FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return (await LoadEntitiesFromCacheAsync(where, orderby, isAsc, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return (await LoadEntitiesFromCacheAsync<TDto>(where, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return (await LoadEntitiesFromCacheAsync<TS, TDto>(where, orderby, isAsc, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheAsync(Expression<Func<T, bool>> @where)
-        {
-            return (await LoadEntitiesFromL2CacheAsync(where)).FirstOrDefault();
-        }
-
-        /// <summary>
-        ///  获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return (await LoadEntitiesFromL2CacheAsync(where, orderby, isAsc)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return (await LoadEntitiesFromL2CacheAsync<TDto>(where)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return (await LoadEntitiesFromL2CacheAsync<TS, TDto>(where, orderby, isAsc)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().AsNoTracking().FirstOrDefault(where);
-        }
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().OrderBy(orderby).AsNoTracking().FirstOrDefault(where) : DataContext.Set<T>().OrderByDescending(orderby).AsNoTracking().FirstOrDefault(where);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(where).AsNoTracking().ProjectToFirstOrDefault<TDto>();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? DataContext.Set<T>().Where(where).OrderBy(orderby).AsNoTracking().ProjectToFirstOrDefault<TDto>() : DataContext.Set<T>().Where(where).OrderByDescending(orderby).AsNoTracking().ProjectToFirstOrDefault<TDto>();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return LoadEntitiesFromCacheNoTracking(where, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return LoadEntitiesFromCacheNoTracking(where, orderby, isAsc, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return LoadEntitiesFromCacheNoTracking<TDto>(where, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return LoadEntitiesFromCacheNoTracking<TS, TDto>(where, orderby, isAsc, timespan).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromL2CacheNoTracking(Expression<Func<T, bool>> @where)
-        {
-            return LoadEntitiesFromL2CacheNoTracking(where).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual T GetFirstEntityFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesFromL2CacheNoTracking(where, orderby, isAsc).FirstOrDefault();
-        }
-
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual TDto GetFirstEntityFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return LoadEntitiesFromL2CacheNoTracking<TDto>(where).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual TDto GetFirstEntityFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadEntitiesFromL2CacheNoTracking<TS, TDto>(where, orderby, isAsc).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return await DataContext.Set<T>().AsNoTracking().FirstOrDefaultAsync(where).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? await DataContext.Set<T>().OrderBy(orderby).AsNoTracking().FirstOrDefaultAsync(where).ConfigureAwait(true) : await DataContext.Set<T>().OrderByDescending(orderby).AsNoTracking().FirstOrDefaultAsync(where).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return await DataContext.Set<T>().Where(where).AsNoTracking().ProjectToFirstOrDefaultAsync<TDto>().ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return isAsc ? await DataContext.Set<T>().Where(where).OrderBy(orderby).AsNoTracking().ProjectToFirstOrDefaultAsync<TDto>().ConfigureAwait(true) : await DataContext.Set<T>().Where(where).OrderByDescending(orderby).AsNoTracking().ProjectToFirstOrDefaultAsync<TDto>().ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30)
-        {
-            return (await LoadEntitiesFromCacheNoTrackingAsync(where, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<T> GetFirstEntityFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-            return (await LoadEntitiesFromCacheNoTrackingAsync(where, orderby, isAsc, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class
-        {
-            return (await LoadEntitiesFromCacheNoTrackingAsync<TDto>(where, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return (await LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc, timespan)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where)
-        {
-            return (await LoadEntitiesFromL2CacheNoTrackingAsync(where)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetFirstEntityFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return (await LoadEntitiesFromL2CacheNoTrackingAsync(where, orderby, isAsc)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where)
-        {
-            return (await LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(where)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        public virtual async Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return (await LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(where, orderby, isAsc)).FirstOrDefault();
-        }
-
-        /// <summary>
-        /// 根据ID找实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        public virtual T GetById(object id)
-        {
-            return DataContext.Set<T>().Find(id);
-        }
-
-        /// <summary>
-        /// 根据ID找实体(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        public virtual async Task<T> GetByIdAsync(object id)
-        {
-            return await DataContext.Set<T>().FindAsync(id).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc)
-        {
-            var temp = DataContext.Set<T>().Where(where);
-            totalCount = temp.Count();
-            if (pageIndex * pageSize > totalCount)
-            {
-                pageIndex = (int)Math.Ceiling(totalCount / (pageSize * 1.0));
-            }
-
-            if (pageIndex <= 0)
-            {
-                pageIndex = 1;
-            }
-
-            return isAsc ? temp.OrderBy(orderby).Skip(pageSize * (pageIndex - 1)).Take(pageSize) : temp.OrderByDescending(orderby).Skip(pageSize * (pageIndex - 1)).Take(pageSize);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            var temp = DataContext.Set<T>().Where(where);
-            totalCount = temp.Count();
-            if (pageIndex * pageSize > totalCount)
-            {
-                pageIndex = (int)Math.Ceiling(totalCount / (pageSize * 1.0));
-            }
-
-            if (pageIndex <= 0)
-            {
-                pageIndex = 1;
-            }
-
-            IOrderedQueryable<T> query;
-            if (isAsc)
-            {
-                query = temp.OrderBy(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenBy(e);
-                    }
-                }
-            }
-            else
-            {
-                query = temp.OrderByDescending(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenByDescending(e);
-                    }
-                }
-            }
-            return query.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30) where TDto : class
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc).Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntities(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            var temp = DataContext.Set<T>().Where(where).AsNoTracking();
-            totalCount = temp.Count();
-            if (pageIndex * pageSize > totalCount)
-            {
-                pageIndex = (int)Math.Ceiling(totalCount / (pageSize * 1.0));
-            }
-
-            if (pageIndex <= 0)
-            {
-                pageIndex = 1;
-            }
-
-            return isAsc ? temp.OrderBy(orderby).Skip(pageSize * (pageIndex - 1)).Take(pageSize) : temp.OrderByDescending(orderby).Skip(pageSize * (pageIndex - 1)).Take(pageSize);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            var temp = DataContext.Set<T>().Where(where).AsNoTracking();
-            totalCount = temp.Count();
-            if (pageIndex * pageSize > totalCount)
-            {
-                pageIndex = (int)Math.Ceiling(totalCount / (pageSize * 1.0));
-            }
-
-            if (pageIndex <= 0)
-            {
-                pageIndex = 1;
-            }
-            IOrderedQueryable<T> query;
-            if (isAsc)
-            {
-                query = temp.OrderBy(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenBy(e);
-                    }
-                }
-            }
-            else
-            {
-                query = temp.OrderByDescending(orderby);
-                if (thenby.Length > 0)
-                {
-                    foreach (var e in thenby)
-                    {
-                        query = query.ThenByDescending(e);
-                    }
-                }
-            }
-            return query.Skip(pageSize * (pageIndex - 1)).Take(pageSize);
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).ProjectToQueryable<TDto>();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30)
-        {
-
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby)
-        {
-
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().FromCache(CachePolicy.WithDurationExpiration(TimeSpan.FromSeconds(timespan)));
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc).Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true)
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        public virtual IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby)
-        {
-            return LoadPageEntitiesNoTracking(pageIndex, pageSize, out totalCount, where, orderby, isAsc, thenby).ProjectToQueryable<TDto>().Cacheable();
-        }
-
-        /// <summary>
-        /// 根据ID删除实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteById(object id)
-        {
-            T t = GetById(id);
-            if (t != null)
-            {
-                DataContext.Entry(t).State = EntityState.Deleted;
-                return true;
-            }
-
-            return false;
-        }
-
-        /// <summary>
-        /// 删除实体
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteEntity(T t)
-        {
-            DataContext.Entry(t).State = EntityState.Unchanged;
-            DataContext.Entry(t).State = EntityState.Deleted;
-            return true;
-        }
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        public virtual int DeleteEntity(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Where(@where).Delete();
-        }
-
-        /// <summary>
-        /// 根据条件删除实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        public virtual async Task<int> DeleteEntityAsync(Expression<Func<T, bool>> @where)
-        {
-            return await DataContext.Set<T>().Where(@where).DeleteAsync().ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 更新实体
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual bool UpdateEntity(T t)
-        {
-            DataContext.Entry(t).State = EntityState.Modified;
-            return true;
-        }
-
-        /// <summary>
-        /// 根据条件更新实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual int UpdateEntity(Expression<Func<T, bool>> @where, T t)
-        {
-            return DataContext.Set<T>().Where(@where).Update(ts => t);
-        }
-
-        /// <summary>
-        /// 根据条件更新实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        public virtual async Task<int> UpdateEntityAsync(Expression<Func<T, bool>> @where, T t)
-        {
-            return await DataContext.Set<T>().Where(@where).UpdateAsync(ts => t).ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 添加实体
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        public virtual T AddEntity(T t)
-        {
-            DataContext.Entry(t).State = EntityState.Added;
-            return t;
-        }
-
-        /// <summary>
-        /// 批量添加实体
-        /// </summary>
-        /// <param name="list">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        public virtual void BulkInsert(IEnumerable<T> list)
-        {
-            DataContext.BulkInsert(list);
-        }
-
-        /// <summary>
-        /// 添加或更新
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        /// <returns></returns>
-        public virtual void AddOrUpdate(Expression<Func<T, object>> exp, params T[] entities)
-        {
-            DataContext.Set<T>().AddOrUpdate(exp, entities);
-        }
-
-        /// <summary>
-        /// 统一保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        public virtual int SaveChanges()
-        {
-            return DataContext.SaveChanges();
-        }
-
-        /// <summary>
-        /// 统一批量保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        public virtual void BulkSaveChanges()
-        {
-            DataContext.BulkSaveChanges();
-        }
-
-        /// <summary>
-        /// 统一保存数据(异步)
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        public virtual async Task<int> SaveChangesAsync()
-        {
-            return await DataContext.SaveChangesAsync().ConfigureAwait(true);
-        }
-
-        /// <summary>
-        /// 判断实体是否在数据库中存在
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        public virtual bool Any(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Any(where);
-        }
-
-        /// <summary>
-        /// 符合条件的个数
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        public virtual int Count(Expression<Func<T, bool>> @where)
-        {
-            return DataContext.Set<T>().Count(where);
-        }
-
-        /// <summary>
-        /// 删除多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        public virtual bool DeleteEntities(IEnumerable<T> list)
-        {
-            list.ForEach(t => { DeleteEntity(t); });
-            return true;
-        }
-
-        /// <summary>
-        /// 更新多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        public virtual bool UpdateEntities(IEnumerable<T> list)
-        {
-            list.ForEach(t => { UpdateEntity(t); });
-            return true;
-        }
-
-        /// <summary>
-        /// 添加多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        public virtual IEnumerable<T> AddEntities(IList<T> list)
-        {
-            //foreach (T t in list)
-            //{
-            //    yield return AddEntity(t);
-            //}
-            DataContext.BulkInsert(list);
-            return list;
-        }
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        /// <returns>泛型集合</returns>
-        public virtual DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters)
-        {
-            return DataContext.Database.SqlQuery<TS>(sql, parameters);
-        }
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        public virtual DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters)
-        {
-            return DataContext.Database.SqlQuery(t, sql, parameters);
-        }
-
-        /// <summary>
-        /// 执行DML语句
-        /// </summary>
-        /// <param name="sql"></param>
-        /// <param name="parameters"></param>
-        public virtual void ExecuteSql(string sql, params SqlParameter[] parameters)
-        {
-            DataContext.Database.ExecuteSqlCommand(TransactionalBehavior.EnsureTransaction, sql, parameters);
-        }
-
-        public override void Dispose(bool disposing)
-        {
-            DataContext?.Dispose();
-            DataContext = null;
-        }
-    }
-}

+ 0 - 130
src/DAL/DAL.csproj

@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{F1A452F8-2757-4130-AECD-4CDCB675419F}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>DAL</RootNamespace>
-    <AssemblyName>DAL</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="AngleSharp, Version=0.9.9.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
-      <HintPath>..\packages\AngleSharp.0.9.11\lib\net45\AngleSharp.dll</HintPath>
-    </Reference>
-    <Reference Include="AutoMapper, Version=8.0.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
-      <HintPath>..\packages\AutoMapper.8.0.0\lib\net461\AutoMapper.dll</HintPath>
-    </Reference>
-    <Reference Include="AutoMapper.EF6, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\AutoMapper.EF6.2.0.0\lib\net461\AutoMapper.EF6.dll</HintPath>
-    </Reference>
-    <Reference Include="DelegateDecompiler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=93b26a10a04705bd, processorArchitecture=MSIL">
-      <HintPath>..\packages\DelegateDecompiler.0.25.0\lib\net45\DelegateDecompiler.dll</HintPath>
-    </Reference>
-    <Reference Include="DelegateDecompiler.EntityFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=93b26a10a04705bd, processorArchitecture=MSIL">
-      <HintPath>..\packages\DelegateDecompiler.EntityFramework.0.25.0\lib\net45\DelegateDecompiler.EntityFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="EFSecondLevelCache, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\EFSecondLevelCache.1.2.0.0\lib\net45\EFSecondLevelCache.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework.Extended, Version=6.0.0.0, Culture=neutral, PublicKeyToken=05b7e29bdd433584, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.Extended.6.1.0.168\lib\net45\EntityFramework.Extended.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="HtmlSanitizer, Version=3.0.0.0, Culture=neutral, PublicKeyToken=61c49a1a9e79cc28, processorArchitecture=MSIL">
-      <HintPath>..\packages\HtmlSanitizer.4.0.204\lib\net45\HtmlSanitizer.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.SharpZipLib, Version=1.1.0.145, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
-      <HintPath>..\packages\SharpZipLib.1.1.0\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="Mono.Reflection, Version=1.1.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>..\packages\Mono.Reflection.Core.1.1.1\lib\net45\Mono.Reflection.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
-    <Reference Include="StackExchange.Redis, Version=1.2.6.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\StackExchange.Redis.1.2.6\lib\net45\StackExchange.Redis.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.DataAnnotations" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.IO.Compression" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
-    </Reference>
-    <Reference Include="Z.EntityFramework.Extensions, Version=3.16.22.0, Culture=neutral, PublicKeyToken=59b66d028979105b, processorArchitecture=MSIL">
-      <HintPath>..\packages\Z.EntityFramework.Extensions.3.16.22\lib\net45\Z.EntityFramework.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="Z.EntityFramework.Plus.EF6, Version=1.8.21.0, Culture=neutral, PublicKeyToken=59b66d028979105b, processorArchitecture=MSIL">
-      <HintPath>..\packages\Z.EntityFramework.Plus.EF6.1.8.21\lib\net45\Z.EntityFramework.Plus.EF6.dll</HintPath>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="BaseDal.cs" />
-    <Compile Include="Dals.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Dals.tt</DependentUpon>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\Masuit.Tools\Masuit.Tools\Masuit.Tools.csproj">
-      <Project>{275d5a0d-c49c-497e-a4b5-f40285c2495f}</Project>
-      <Name>Masuit.Tools</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\IDAL\IDAL.csproj">
-      <Project>{7997fb01-c9c1-4793-a430-9ca3c3852b37}</Project>
-      <Name>IDAL</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Models\Models.csproj">
-      <Project>{5400CA01-CBCF-4531-A388-3057393D5B4F}</Project>
-      <Name>Models</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Dals.tt">
-      <Generator>TextTemplatingFileGenerator</Generator>
-      <LastGenOutput>Dals.cs</LastGenOutput>
-    </Content>
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 28
src/DAL/Dals.cs

@@ -1,28 +0,0 @@
-
-using IDAL;
-using Models.Entity;
-using System;
-namespace DAL
-{
-	public partial class BroadcastDal :BaseDal<Broadcast>,IBroadcastDal{}
-	public partial class CategoryDal :BaseDal<Category>,ICategoryDal{}
-	public partial class CommentDal :BaseDal<Comment>,ICommentDal{}
-	public partial class ContactsDal :BaseDal<Contacts>,IContactsDal{}
-	public partial class DonateDal :BaseDal<Donate>,IDonateDal{}
-	public partial class FastShareDal :BaseDal<FastShare>,IFastShareDal{}
-	public partial class InternalMessageDal :BaseDal<InternalMessage>,IInternalMessageDal{}
-	public partial class IssueDal :BaseDal<Issue>,IIssueDal{}
-	public partial class LeaveMessageDal :BaseDal<LeaveMessage>,ILeaveMessageDal{}
-	public partial class LinksDal :BaseDal<Links>,ILinksDal{}
-	public partial class LoginRecordDal :BaseDal<LoginRecord>,ILoginRecordDal{}
-	public partial class MenuDal :BaseDal<Menu>,IMenuDal{}
-	public partial class MiscDal :BaseDal<Misc>,IMiscDal{}
-	public partial class NoticeDal :BaseDal<Notice>,INoticeDal{}
-	public partial class PostDal :BaseDal<Post>,IPostDal{}
-	public partial class PostAccessRecordDal :BaseDal<PostAccessRecord>,IPostAccessRecordDal{}
-	public partial class PostHistoryVersionDal :BaseDal<PostHistoryVersion>,IPostHistoryVersionDal{}
-	public partial class SearchDetailsDal :BaseDal<SearchDetails>,ISearchDetailsDal{}
-	public partial class SeminarDal :BaseDal<Seminar>,ISeminarDal{}
-	public partial class SystemSettingDal :BaseDal<SystemSetting>,ISystemSettingDal{}
-	public partial class UserInfoDal :BaseDal<UserInfo>,IUserInfoDal{}
-}

+ 0 - 24
src/DAL/Dals.tt

@@ -1,24 +0,0 @@
-<#@ template language="C#" debug="false" hostspecific="true"#>
-<#@ include file="EF.Utility.CS.ttinclude"#>
-<#@output extension=".cs"#>
-<#
-CodeGenerationTools code = new CodeGenerationTools(this);
-MetadataLoader loader = new MetadataLoader(this);
-CodeRegion region = new CodeRegion(this, 1);
-MetadataTools ef = new MetadataTools(this);
-string inputFile = @"..\\ModelCodeGenerate\\Model.edmx";//EF模型路径
-EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
-string namespaceName = code.VsNamespaceSuggestion();
-EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
-#>
-using IDAL;
-using Models.Entity;
-using System;
-namespace DAL
-{
-<#
-foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
-{#>
-	public partial class <#=entity.Name#>Dal :BaseDal<<#=entity.Name#>>,I<#=entity.Name#>Dal{}
-<#}#>
-}

+ 0 - 36
src/DAL/Properties/AssemblyInfo.cs

@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("DAL")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("DAL")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 会使此程序集中的类型
-//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("f1a452f8-2757-4130-aecd-4cdcb675419f")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 21
src/DAL/packages.config

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="AngleSharp" version="0.9.11" targetFramework="net461" />
-  <package id="AutoMapper" version="8.0.0" targetFramework="net461" />
-  <package id="AutoMapper.EF6" version="2.0.0" targetFramework="net461" />
-  <package id="DelegateDecompiler" version="0.25.0" targetFramework="net461" />
-  <package id="DelegateDecompiler.EntityFramework" version="0.25.0" targetFramework="net461" />
-  <package id="EFSecondLevelCache" version="1.2.0.0" targetFramework="net45" />
-  <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
-  <package id="EntityFramework.Extended" version="6.1.0.168" targetFramework="net45" />
-  <package id="EntityFramework.zh-Hans" version="6.2.0" targetFramework="net45" />
-  <package id="HtmlSanitizer" version="4.0.204" targetFramework="net461" />
-  <package id="Mono.Reflection" version="1.1.0.0" targetFramework="net45" />
-  <package id="Mono.Reflection.Core" version="1.1.1" targetFramework="net461" />
-  <package id="Newtonsoft.Json" version="12.0.1" targetFramework="net461" />
-  <package id="SharpZipLib" version="1.1.0" targetFramework="net461" />
-  <package id="StackExchange.Redis" version="1.2.6" targetFramework="net45" requireReinstallation="true" />
-  <package id="System.ValueTuple" version="4.5.0" targetFramework="net45" requireReinstallation="true" />
-  <package id="Z.EntityFramework.Extensions" version="3.16.22" targetFramework="net461" />
-  <package id="Z.EntityFramework.Plus.EF6" version="1.8.21" targetFramework="net461" />
-</packages>

+ 0 - 44
src/Factory/Factory.cs

@@ -1,44 +0,0 @@
-using System;
-using System.Configuration;
-using System.IO;
-using System.Reflection;
-
-namespace DALFactory
-{
-    /// <summary>
-    /// 反射工厂
-    /// </summary>
-    public static class Factory
-    {
-        /// <summary>
-        /// 根据配置文件中的方式进行反射创建对象
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="fullNamespace">程序集全命名空间</param>
-        /// <returns></returns>
-        /// <exception cref="Exception"></exception>
-        public static T CreateInstance<T>(string fullNamespace)
-        {
-            try
-            {
-                string dalNameSpace = ConfigurationManager.AppSettings["DalNameSpace"] ?? "DAL";//根据命名空间创建实例对象
-                Assembly ass = Assembly.Load(dalNameSpace);
-                return (T)ass.CreateInstance(fullNamespace);
-            }
-            catch
-            {
-                try
-                {
-                    string dalPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", ConfigurationManager.AppSettings["DalPath"] ?? "DAL.dll");//根据程序集路径创建实例对象
-                    Assembly ass = Assembly.LoadFile(dalPath);
-                    return (T)ass.CreateInstance(fullNamespace);
-                }
-                catch
-                {
-                    //都出错则往外抛异常
-                    throw new Exception("找不到程序集");
-                }
-            }
-        }
-    }
-}

+ 0 - 45
src/Factory/Factory.csproj

@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{1363B3D8-457C-4A8C-BAD4-228BC9141A4C}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Factory</RootNamespace>
-    <AssemblyName>Factory</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Core" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Factory.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 81
src/Factory/ObjectPool.cs

@@ -1,81 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Configuration;
-using System.IO;
-using System.Reflection;
-
-namespace DALFactory
-{
-    /// <summary>
-    /// 对象池
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class ObjectPool<T> : ConcurrentQueue<T> where T : class
-    {
-        private int Limit { get; set; }
-
-        public ObjectPool(int limit = 32)
-        {
-            Limit = limit;
-        }
-
-        public ObjectPool(List<T> list) : base(list)
-        {
-            Limit = list.Count;
-        }
-
-        public new void Enqueue(T item)
-        {
-            if (Count >= Limit)
-            {
-                TryDequeue(out var _);
-            }
-
-            base.Enqueue(item);
-        }
-        public T Dequeue(string fullNamespace)
-        {
-            if (Count < 1 || IsEmpty)
-            {
-                for (int i = 0; i < Limit; i++)
-                {
-                    Enqueue(GetInstance(fullNamespace));
-                }
-            }
-            TryDequeue(out var t);
-            return t ?? GetInstance(fullNamespace);
-        }
-
-        /// <summary>
-        /// 根据配置文件中的方式进行反射创建对象
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="fullNamespace">程序集全命名空间</param>
-        /// <returns></returns>
-        /// <exception cref="Exception"></exception>
-        public static T GetInstance(string fullNamespace)
-        {
-            try
-            {
-                string DalNameSpace = ConfigurationManager.AppSettings["DalNameSpace"] ?? "DAL";//根据命名空间创建实例对象
-                Assembly ass = Assembly.Load(DalNameSpace);
-                return (T)ass.CreateInstance(fullNamespace);
-            }
-            catch (Exception)
-            {
-                try
-                {
-                    string DalPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", ConfigurationManager.AppSettings["DalPath"] ?? "DAL.dll");//根据程序集路径创建实例对象
-                    Assembly ass = Assembly.LoadFile(DalPath);
-                    return (T)ass.CreateInstance(fullNamespace);
-                }
-                catch (Exception)
-                {
-                    //都出错则往外抛异常
-                    throw new Exception("找不到程序集");
-                }
-            }
-        }
-    }
-}

+ 0 - 36
src/Factory/Properties/AssemblyInfo.cs

@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("Factory")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Factory")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 会使此程序集中的类型
-//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("d927561b-5ed4-4599-8209-16f9d1f5461d")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 29
src/IBLL/App.config

@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <configSections>
-    
-    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
-  <entityFramework>
-    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
-      <parameters>
-        <parameter value="mssqllocaldb" />
-      </parameters>
-    </defaultConnectionFactory>
-    <providers>
-      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
-    </providers>
-  </entityFramework>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.1.0" newVersion="7.0.1.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="AngleSharp" publicKeyToken="e83494dcdc6d31ea" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-0.10.1.0" newVersion="0.10.1.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration>

+ 0 - 87
src/IBLL/IBLL.csproj

@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{939493B4-A47C-43E2-99E3-92459CD0EB1E}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>IBLL</RootNamespace>
-    <AssemblyName>IBLL</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="EFSecondLevelCache, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\EFSecondLevelCache.1.2.0.0\lib\net45\EFSecondLevelCache.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.DataAnnotations" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Data" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="IBaseBll.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>IBaseBll.tt</DependentUpon>
-    </Compile>
-    <Compile Include="ICategoryBll.cs" />
-    <Compile Include="ICommentBll.cs" />
-    <Compile Include="ILeaveMessageBll.cs" />
-    <Compile Include="IMenuBll.cs" />
-    <Compile Include="IPostBll.cs" />
-    <Compile Include="IUserInfoBll.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="IBaseBll.tt">
-      <Generator>TextTemplatingFileGenerator</Generator>
-      <LastGenOutput>IBaseBll.cs</LastGenOutput>
-    </Content>
-    <Content Include="readme.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\IDAL\IDAL.csproj">
-      <Project>{7997FB01-C9C1-4793-A430-9CA3C3852B37}</Project>
-      <Name>IDAL</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Models\Models.csproj">
-      <Project>{5400CA01-CBCF-4531-A388-3057393D5B4F}</Project>
-      <Name>Models</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 2246
src/IBLL/IBaseBll.cs

@@ -1,2246 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Data.Entity.Infrastructure;
-using System.Data.SqlClient;
-using System.Threading.Tasks;
-using EFSecondLevelCache;
-using Models.Entity;
-namespace IBLL
-{
-    public interface IBaseBll<T>
-    {
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAll();
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAllNoTracking();
-
-        /// <summary>
-        /// 从一级缓存获取所有实体
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从一级缓存获取所有实体(异步)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2Cache();
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2CacheNoTracking();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntities(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntities<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntitiesNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntity<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntity<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        ///  获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 根据ID找实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        T GetById(object id);
-
-        /// <summary>
-        /// 根据ID找实体(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        Task<T> GetByIdAsync(object id);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 根据ID删除实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        bool DeleteById(object id);
-
-        /// <summary>
-        /// 根据ID删除实体并保存
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        bool DeleteByIdSaved(object id);
-
-        /// <summary>
-        /// 根据ID删除实体并保存(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteByIdSavedAsync(object id);
-
-        /// <summary>
-        /// 删除实体并保存
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntity(T t);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        int DeleteEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        int DeleteEntitySaved(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntitySavedAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 删除实体并保存
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntitySaved(T t);
-
-        /// <summary>
-        /// 删除实体并保存(异步)
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntitySavedAsync(T t);
-
-        /// <summary>
-        /// 更新实体
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntity(T t);
-
-        /// <summary>
-        /// 更新实体并保存
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntitySaved(T t);
-
-        /// <summary>
-        /// 更新实体并保存(异步)
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntitySavedAsync(T t);
-
-        /// <summary>
-        /// 根据条件更新实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        int UpdateEntity(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 根据条件更新实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntityAsync(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 添加实体
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        T AddEntity(T t);
-
-        /// <summary>
-        /// 添加实体并保存
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        T AddEntitySaved(T t);
-
-        /// <summary>
-        /// 添加实体并保存(异步)
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        Task<int> AddEntitySavedAsync(T t);
-
-        /// <summary>
-        /// 添加或更新
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        void AddOrUpdate(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 添加或更新并保存
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        int AddOrUpdateSaved(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 添加或更新并保存(异步)
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        Task<int> AddOrUpdateSavedAsync(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 统一保存的方法
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        int SaveChanges();
-
-        /// <summary>
-        /// 统一保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        Task<int> SaveChangesAsync();
-
-        /// <summary>
-        /// 判断实体是否在数据库中存在
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        bool Any(Expression<Func<T, bool>> @where);
-        
-        /// <summary>
-        /// 统计符合条件的个数
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns></returns>
-        int Count(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 删除多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 删除多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntitiesSaved(IEnumerable<T> list);
-
-        /// <summary>
-        /// 删除多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntitiesSavedAsync(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntitiesSaved(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntitiesSavedAsync(IEnumerable<T> list);
-
-        /// <summary>
-        /// 添加多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        IEnumerable<T> AddEntities(IList<T> list);
-
-        /// <summary>
-        /// 添加多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        Task<IEnumerable<T>> AddEntitiesAsync(IList<T> list);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        /// <returns>泛型集合</returns>
-        DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行DML语句
-        /// </summary>
-        /// <param name="sql"></param>
-        /// <param name="parameters"></param>
-        void ExecuteSql(string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 批量添加实体
-        /// </summary>
-        /// <param name="list">需要添加的实体</param>
-        void BulkInsert(IEnumerable<T> list);
-
-        /// <summary>
-        /// 统一批量保存数据
-        /// </summary>
-        void BulkSaveChanges();
-    }
-	
-	public partial interface IBroadcastBll : IBaseBll<Broadcast>{}   
-	
-	public partial interface ICategoryBll : IBaseBll<Category>{}   
-	
-	public partial interface ICommentBll : IBaseBll<Comment>{}   
-	
-	public partial interface IContactsBll : IBaseBll<Contacts>{}   
-	
-	public partial interface IDonateBll : IBaseBll<Donate>{}   
-	
-	public partial interface IFastShareBll : IBaseBll<FastShare>{}   
-	
-	public partial interface IInternalMessageBll : IBaseBll<InternalMessage>{}   
-	
-	public partial interface IIssueBll : IBaseBll<Issue>{}   
-	
-	public partial interface ILeaveMessageBll : IBaseBll<LeaveMessage>{}   
-	
-	public partial interface ILinksBll : IBaseBll<Links>{}   
-	
-	public partial interface ILoginRecordBll : IBaseBll<LoginRecord>{}   
-	
-	public partial interface IMenuBll : IBaseBll<Menu>{}   
-	
-	public partial interface IMiscBll : IBaseBll<Misc>{}   
-	
-	public partial interface INoticeBll : IBaseBll<Notice>{}   
-	
-	public partial interface IPostBll : IBaseBll<Post>{}   
-	
-	public partial interface IPostAccessRecordBll : IBaseBll<PostAccessRecord>{}   
-	
-	public partial interface IPostHistoryVersionBll : IBaseBll<PostHistoryVersion>{}   
-	
-	public partial interface ISearchDetailsBll : IBaseBll<SearchDetails>{}   
-	
-	public partial interface ISeminarBll : IBaseBll<Seminar>{}   
-	
-	public partial interface ISystemSettingBll : IBaseBll<SystemSetting>{}   
-	
-	public partial interface IUserInfoBll : IBaseBll<UserInfo>{}   
-	
-}

+ 0 - 2220
src/IBLL/IBaseBll.tt

@@ -1,2220 +0,0 @@
-<#@ template language="C#" debug="false" hostspecific="true"#>
-<#@ include file="EF.Utility.CS.ttinclude"#>
-<#@ output extension=".cs"#>
-<#
-CodeGenerationTools code = new CodeGenerationTools(this);
-MetadataLoader loader = new MetadataLoader(this);
-CodeRegion region = new CodeRegion(this, 1);
-MetadataTools ef = new MetadataTools(this);
-string inputFile = @"..\\ModelCodeGenerate\\Model.edmx";//EF模型路径
-EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
-string namespaceName = code.VsNamespaceSuggestion();
-EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
-#>
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Data.Entity.Infrastructure;
-using System.Data.SqlClient;
-using System.Threading.Tasks;
-using EFSecondLevelCache;
-using Models.Entity;
-namespace IBLL
-{
-    public interface IBaseBll<T>
-    {
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAll();
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAllNoTracking();
-
-        /// <summary>
-        /// 从一级缓存获取所有实体
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从一级缓存获取所有实体(异步)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2Cache();
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2CacheNoTracking();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntities(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntities<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntitiesNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntity<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntity<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        ///  获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 根据ID找实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        T GetById(object id);
-
-        /// <summary>
-        /// 根据ID找实体(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        Task<T> GetByIdAsync(object id);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 根据ID删除实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        bool DeleteById(object id);
-
-        /// <summary>
-        /// 根据ID删除实体并保存
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        bool DeleteByIdSaved(object id);
-
-        /// <summary>
-        /// 根据ID删除实体并保存(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteByIdSavedAsync(object id);
-
-        /// <summary>
-        /// 删除实体并保存
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntity(T t);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        int DeleteEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        int DeleteEntitySaved(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntitySavedAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 删除实体并保存
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntitySaved(T t);
-
-        /// <summary>
-        /// 删除实体并保存(异步)
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntitySavedAsync(T t);
-
-        /// <summary>
-        /// 更新实体
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntity(T t);
-
-        /// <summary>
-        /// 更新实体并保存
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntitySaved(T t);
-
-        /// <summary>
-        /// 更新实体并保存(异步)
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntitySavedAsync(T t);
-
-        /// <summary>
-        /// 根据条件更新实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        int UpdateEntity(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 根据条件更新实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntityAsync(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 添加实体
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        T AddEntity(T t);
-
-        /// <summary>
-        /// 添加实体并保存
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        T AddEntitySaved(T t);
-
-        /// <summary>
-        /// 添加实体并保存(异步)
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        Task<int> AddEntitySavedAsync(T t);
-
-        /// <summary>
-        /// 添加或更新
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        void AddOrUpdate(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 添加或更新并保存
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        int AddOrUpdateSaved(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 添加或更新并保存(异步)
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        Task<int> AddOrUpdateSavedAsync(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 统一保存的方法
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        int SaveChanges();
-
-        /// <summary>
-        /// 统一保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        Task<int> SaveChangesAsync();
-
-        /// <summary>
-        /// 判断实体是否在数据库中存在
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        bool Any(Expression<Func<T, bool>> @where);
-        
-        /// <summary>
-        /// 统计符合条件的个数
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns></returns>
-        int Count(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 删除多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 删除多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntitiesSaved(IEnumerable<T> list);
-
-        /// <summary>
-        /// 删除多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntitiesSavedAsync(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntitiesSaved(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntitiesSavedAsync(IEnumerable<T> list);
-
-        /// <summary>
-        /// 添加多个实体并保存
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        IEnumerable<T> AddEntities(IList<T> list);
-
-        /// <summary>
-        /// 添加多个实体并保存(异步)
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        Task<IEnumerable<T>> AddEntitiesAsync(IList<T> list);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        /// <returns>泛型集合</returns>
-        DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行DML语句
-        /// </summary>
-        /// <param name="sql"></param>
-        /// <param name="parameters"></param>
-        void ExecuteSql(string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 批量添加实体
-        /// </summary>
-        /// <param name="list">需要添加的实体</param>
-        void BulkInsert(IEnumerable<T> list);
-
-        /// <summary>
-        /// 统一批量保存数据
-        /// </summary>
-        void BulkSaveChanges();
-    }
-<#
-foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
-{#>	
-	public partial interface I<#=entity.Name#>Bll : IBaseBll<<#=entity.Name#>>{}   
-<#}#>	
-}

+ 0 - 16
src/IBLL/IMenuBll.cs

@@ -1,16 +0,0 @@
-using Models.Entity;
-using System.Data.Entity.Infrastructure;
-
-namespace IBLL
-{
-    public partial interface IMenuBll
-    {
-        /// <summary>
-        /// 通过存储过程获得自己以及自己所有的子元素集合
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        DbRawSqlQuery<Menu> GetChildrenMenusByParentId(int id);
-
-    }
-}

+ 0 - 36
src/IBLL/Properties/AssemblyInfo.cs

@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("IBLL")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("IBLL")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 会使此程序集中的类型
-//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("939493b4-a47c-43e2-99e3-92459cd0eb1e")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 5
src/IBLL/packages.config

@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="EFSecondLevelCache" version="1.2.0.0" targetFramework="net45" />
-  <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
-</packages>

+ 0 - 70
src/IBLL/readme.txt

@@ -1,70 +0,0 @@
-EFSecondLevelCache
-=======
-Entity Framework 6.x Second Level Caching Library.
-
-Second level caching is a query cache. The results of EF commands will be stored in the cache,
-so that the same EF commands will retrieve their data from the cache rather than executing them
-against the database again.
-
-
-Usage:
-1- Setting up the cache invalidation by overriding the SaveChanges method to prevent stale reads:
-
-namespace EFSecondLevelCache.TestDataLayer.DataLayer
-{
-	public class SampleContext : DbContext
-	{
-		// public DbSet<Product> Products { get; set; }
-
-		public SampleContext()
-			: base("connectionString1")
-		{
-		}
-
-		public override int SaveChanges()
-		{
-			return SaveAllChanges(invalidateCacheDependencies: true);
-		}
-
-		public int SaveAllChanges(bool invalidateCacheDependencies = true)
-		{
-			var changedEntityNames = getChangedEntityNames();
-			var result = base.SaveChanges();
-			if (invalidateCacheDependencies)
-			{
-				new EFCacheServiceProvider().InvalidateCacheDependencies(changedEntityNames);
-			}
-			return result;
-		}
-
-		private string[] getChangedEntityNames()
-		{
-			// Updated version of this method: \EFSecondLevelCache\EFSecondLevelCache.Tests\EFSecondLevelCache.TestDataLayer\DataLayer\SampleContext.cs
-			return this.ChangeTracker.Entries()
-				.Where(x => x.State == EntityState.Added ||
-							x.State == EntityState.Modified ||
-							x.State == EntityState.Deleted)
-				.Select(x => System.Data.Entity.Core.Objects.ObjectContext.GetObjectType(x.Entity.GetType()).FullName)
-				.Distinct()
-				.ToArray();
-		}
-	}
-}
-
-Sometimes you don't want to invalidate the cache when non important properties such as NumberOfViews are updated.
-In these cases, try SaveAllChanges(invalidateCacheDependencies: false), before updating the data.
-
-2- Then to cache the results of the normal queries like:
-var products = context.Products.Include(x => x.Tags).FirstOrDefault();
-
-We can use the new `Cacheable()` extension method:
-var products = context.Products.Include(x => x.Tags).Cacheable().FirstOrDefault(); // Async methods are supported too.
-
-
-Notes:
-Good candidates for query caching are global site's settings, list of public articles or comments
-and not frequently changed, private or specific data to each user.
-If a page requires authentication, its data shouldn't be cached.
-
-Project's Url:
-https://github.com/VahidN/EFSecondLevelCache

+ 0 - 29
src/IDAL/App.config

@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <configSections>
-    
-    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
-  <entityFramework>
-    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
-      <parameters>
-        <parameter value="mssqllocaldb" />
-      </parameters>
-    </defaultConnectionFactory>
-    <providers>
-      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
-    </providers>
-  </entityFramework>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-7.0.1.0" newVersion="7.0.1.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="AngleSharp" publicKeyToken="e83494dcdc6d31ea" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-0.10.1.0" newVersion="0.10.1.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration>

+ 0 - 2133
src/IDAL/IBaseDal.cs

@@ -1,2133 +0,0 @@
-
- 
-using System;
-using System.Collections.Generic;
-using System.Data.Entity.Infrastructure;
-using System.Data.SqlClient;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
-using EFSecondLevelCache;
-using Models.Entity;
-namespace IDAL
-{   
-	public interface IBaseDal<T> : IDisposable where T : class, new()
-    {
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAll();
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAllNoTracking();
-
-        /// <summary>
-        /// 从一级缓存获取所有实体
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从一级缓存获取所有实体(异步)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2Cache();
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2CacheNoTracking();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntities(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntities<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntitiesNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntity<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntity<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        ///  获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 根据ID找实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        T GetById(object id);
-
-        /// <summary>
-        /// 根据ID找实体(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        Task<T> GetByIdAsync(object id);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 根据ID删除实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        bool DeleteById(object id);
-
-        /// <summary>
-        /// 删除实体
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntity(T t);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        int DeleteEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 更新实体
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntity(T t);
-
-        /// <summary>
-        /// 根据条件更新实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        int UpdateEntity(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 根据条件更新实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntityAsync(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 添加实体
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        T AddEntity(T t);
-
-        /// <summary>
-        /// 批量添加实体
-        /// </summary>
-        /// <param name="list">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        void BulkInsert(IEnumerable<T> list);
-
-        /// <summary>
-        /// 添加或更新
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        /// <returns></returns>
-        void AddOrUpdate(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 统一保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        int SaveChanges();
-
-        /// <summary>
-        /// 统一批量保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        void BulkSaveChanges();
-
-        /// <summary>
-        /// 统一保存数据(异步)
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        Task<int> SaveChangesAsync();
-
-        /// <summary>
-        /// 判断实体是否在数据库中存在
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        bool Any(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 符合条件的个数
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        int Count(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 删除多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 添加多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        IEnumerable<T> AddEntities(IList<T> list);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        /// <returns>泛型集合</returns>
-        DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行DML语句
-        /// </summary>
-        /// <param name="sql"></param>
-        /// <param name="parameters"></param>
-        void ExecuteSql(string sql, params SqlParameter[] parameters);
-
-        void Dispose(bool disposing);
-    }
-	
-	public partial interface IBroadcastDal :IBaseDal<Broadcast>{}
-	
-	public partial interface ICategoryDal :IBaseDal<Category>{}
-	
-	public partial interface ICommentDal :IBaseDal<Comment>{}
-	
-	public partial interface IContactsDal :IBaseDal<Contacts>{}
-	
-	public partial interface IDonateDal :IBaseDal<Donate>{}
-	
-	public partial interface IFastShareDal :IBaseDal<FastShare>{}
-	
-	public partial interface IInternalMessageDal :IBaseDal<InternalMessage>{}
-	
-	public partial interface IIssueDal :IBaseDal<Issue>{}
-	
-	public partial interface ILeaveMessageDal :IBaseDal<LeaveMessage>{}
-	
-	public partial interface ILinksDal :IBaseDal<Links>{}
-	
-	public partial interface ILoginRecordDal :IBaseDal<LoginRecord>{}
-	
-	public partial interface IMenuDal :IBaseDal<Menu>{}
-	
-	public partial interface IMiscDal :IBaseDal<Misc>{}
-	
-	public partial interface INoticeDal :IBaseDal<Notice>{}
-	
-	public partial interface IPostDal :IBaseDal<Post>{}
-	
-	public partial interface IPostAccessRecordDal :IBaseDal<PostAccessRecord>{}
-	
-	public partial interface IPostHistoryVersionDal :IBaseDal<PostHistoryVersion>{}
-	
-	public partial interface ISearchDetailsDal :IBaseDal<SearchDetails>{}
-	
-	public partial interface ISeminarDal :IBaseDal<Seminar>{}
-	
-	public partial interface ISystemSettingDal :IBaseDal<SystemSetting>{}
-	
-	public partial interface IUserInfoDal :IBaseDal<UserInfo>{}
-	
-}

+ 0 - 2104
src/IDAL/IBaseDal.tt

@@ -1,2104 +0,0 @@
-<#@ template language="C#" debug="false" hostspecific="true"#>
-<#@ include file="EF.Utility.CS.ttinclude"#>
-<#@ output extension=".cs"#> 
-<# CodeGenerationTools code = new CodeGenerationTools(this);
-MetadataLoader loader = new MetadataLoader(this);
-CodeRegion region = new CodeRegion(this, 1);
-MetadataTools ef = new MetadataTools(this);
-string inputFile = @"..\\ModelCodeGenerate\\Model.edmx";//EF模型路径
-EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
-string namespaceName = code.VsNamespaceSuggestion();
-EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #>
-using System;
-using System.Collections.Generic;
-using System.Data.Entity.Infrastructure;
-using System.Data.SqlClient;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
-using EFSecondLevelCache;
-using Models.Entity;
-namespace IDAL
-{   
-	public interface IBaseDal<T> : IDisposable where T : class, new()
-    {
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAll();
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> GetAllNoTracking();
-
-        /// <summary>
-        /// 从一级缓存获取所有实体
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking(int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体(不跟踪)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从一级缓存获取所有实体(异步)
-        /// </summary>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync(int timespan = 20);
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2Cache();
-
-        /// <summary>
-        /// 从二级缓存获取所有实体
-        /// </summary>
-        /// <returns>还未执行的SQL语句</returns>
-        EFCachedQueryable<T> GetAllFromL2CacheNoTracking();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TDto>(int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TDto>();
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAll<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> GetAllNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromCacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> GetAllFromCacheNoTrackingAsync<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2Cache<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> GetAllFromL2CacheNoTracking<TS>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAll<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> GetAllNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="thenby">次排序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromCacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> GetAllFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 20, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2Cache<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true) where TDto : class;
-
-        /// <summary>
-        /// 获取所有实体
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> GetAllFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntities(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntities<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntities<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        /// <returns></returns>
-        IQueryable<TDto> LoadEntities<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns></returns>
-        IEnumerable<T> LoadEntitiesFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IOrderedQueryable<T>> LoadEntitiesAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadEntitiesNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IOrderedQueryable<T> LoadEntitiesNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadEntitiesNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadEntitiesFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadEntitiesFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<T>> LoadEntitiesNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IQueryable<TDto>> LoadEntitiesNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<T>> LoadEntitiesFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体集合</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<IEnumerable<TDto>> LoadEntitiesFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        ///  基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<T>> LoadEntitiesFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        ///  基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体集合</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 基本查询方法,获取一个被AutoMapper映射后的集合,优先从二级缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序字段</typeparam>
-        /// <typeparam name="TDto">输出类型</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序方式</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        Task<EFCachedQueryable<TDto>> LoadEntitiesFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntity<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntity<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntity<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCache(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromCache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCache<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2Cache(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        T GetFirstEntityFromL2Cache<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2Cache<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2Cache<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        ///  获取第一条数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(异步)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromCacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromCacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        T GetFirstEntityFromL2CacheNoTracking<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从二级缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        TDto GetFirstEntityFromL2CacheNoTracking<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync(Expression<Func<T, bool>> @where, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<T> GetFirstEntityFromCacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromCacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>实体</returns>
-        Task<T> GetFirstEntityFromL2CacheNoTrackingAsync<TS>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TDto>(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 获取第一条被AutoMapper映射后的数据,优先从缓存读取(异步,不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS">排序</typeparam>
-        /// <typeparam name="TDto">映射实体</typeparam>
-        /// <param name="where">查询条件</param>
-        /// <param name="orderby">排序字段</param>
-        /// <param name="isAsc">是否升序</param>
-        /// <returns>映射实体</returns>
-        Task<TDto> GetFirstEntityFromL2CacheNoTrackingAsync<TS, TDto>(Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 根据ID找实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        T GetById(object id);
-
-        /// <summary>
-        /// 根据ID找实体(异步)
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>实体</returns>
-        Task<T> GetByIdAsync(object id);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntities<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> where, Expression<Func<T, TS>> orderby, bool isAsc, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2Cache<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从二级缓存读取,取出被AutoMapper映射后的数据集合
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2Cache<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<T> LoadPageEntitiesNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IQueryable<TDto> LoadPageEntitiesNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromCacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <param name="timespan">缓存过期时间</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromCacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, int timespan = 30, params Expression<Func<T, TS>>[] thenby) where TDto : class;
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<T> LoadPageEntitiesFromL2CacheNoTracking<TS>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true);
-
-        /// <summary>
-        /// 高效分页查询方法,取出被AutoMapper映射后的数据集合,优先从缓存读取(不跟踪实体)
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <typeparam name="TDto"></typeparam>
-        /// <param name="pageIndex">第几页</param>
-        /// <param name="pageSize">每页大小</param>
-        /// <param name="totalCount">数据总数</param>
-        /// <param name="where">where Lambda条件表达式</param>
-        /// <param name="orderby">orderby Lambda条件表达式</param>
-        /// <param name="isAsc">升序降序</param>
-        /// <returns>还未执行的SQL语句</returns>
-        IEnumerable<TDto> LoadPageEntitiesFromL2CacheNoTracking<TS, TDto>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> @where, Expression<Func<T, TS>> @orderby, bool isAsc = true, params Expression<Func<T, TS>>[] thenby);
-
-        /// <summary>
-        /// 根据ID删除实体
-        /// </summary>
-        /// <param name="id">实体id</param>
-        /// <returns>删除成功</returns>
-        bool DeleteById(object id);
-
-        /// <summary>
-        /// 删除实体
-        /// </summary>
-        /// <param name="t">需要删除的实体</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntity(T t);
-
-        /// <summary>
-        /// 根据条件删除实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        int DeleteEntity(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 根据条件删除实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>删除成功</returns>
-        Task<int> DeleteEntityAsync(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 更新实体
-        /// </summary>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntity(T t);
-
-        /// <summary>
-        /// 根据条件更新实体
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        int UpdateEntity(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 根据条件更新实体(异步)
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <param name="t">更新后的实体</param>
-        /// <returns>更新成功</returns>
-        Task<int> UpdateEntityAsync(Expression<Func<T, bool>> @where, T t);
-
-        /// <summary>
-        /// 添加实体
-        /// </summary>
-        /// <param name="t">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        T AddEntity(T t);
-
-        /// <summary>
-        /// 批量添加实体
-        /// </summary>
-        /// <param name="list">需要添加的实体</param>
-        /// <returns>添加成功</returns>
-        void BulkInsert(IEnumerable<T> list);
-
-        /// <summary>
-        /// 添加或更新
-        /// </summary>
-        /// <param name="exp">更新条件</param>
-        /// <param name="entities">实体集合</param>
-        /// <returns></returns>
-        void AddOrUpdate(Expression<Func<T, object>> exp, params T[] entities);
-
-        /// <summary>
-        /// 统一保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        int SaveChanges();
-
-        /// <summary>
-        /// 统一批量保存数据
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        void BulkSaveChanges();
-
-        /// <summary>
-        /// 统一保存数据(异步)
-        /// </summary>
-        /// <returns>受影响的行数</returns>
-        Task<int> SaveChangesAsync();
-
-        /// <summary>
-        /// 判断实体是否在数据库中存在
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        bool Any(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 符合条件的个数
-        /// </summary>
-        /// <param name="where">查询条件</param>
-        /// <returns>是否存在</returns>
-        int Count(Expression<Func<T, bool>> @where);
-
-        /// <summary>
-        /// 删除多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>删除成功</returns>
-        bool DeleteEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 更新多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>更新成功</returns>
-        bool UpdateEntities(IEnumerable<T> list);
-
-        /// <summary>
-        /// 添加多个实体
-        /// </summary>
-        /// <param name="list">实体集合</param>
-        /// <returns>添加成功</returns>
-        IEnumerable<T> AddEntities(IList<T> list);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="TS"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        /// <returns>泛型集合</returns>
-        DbRawSqlQuery<TS> SqlQuery<TS>(string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行查询语句
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="parameters">参数</param>
-        DbRawSqlQuery SqlQuery(Type t, string sql, params SqlParameter[] parameters);
-
-        /// <summary>
-        /// 执行DML语句
-        /// </summary>
-        /// <param name="sql"></param>
-        /// <param name="parameters"></param>
-        void ExecuteSql(string sql, params SqlParameter[] parameters);
-
-        void Dispose(bool disposing);
-    }
-<#
-foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
-{#>	
-	public partial interface I<#=entity.Name#>Dal :IBaseDal<<#=entity.Name#>>{}
-<#}#>	
-}

+ 0 - 77
src/IDAL/IDAL.csproj

@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{7997FB01-C9C1-4793-A430-9CA3C3852B37}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>IDAL</RootNamespace>
-    <AssemblyName>IDAL</AssemblyName>
-    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="EFSecondLevelCache, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\EFSecondLevelCache.1.2.0.0\lib\net45\EFSecondLevelCache.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
-      <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.DataAnnotations" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Data" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="IBaseDal.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>IBaseDal.tt</DependentUpon>
-    </Compile>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="IBaseDal.tt">
-      <Generator>TextTemplatingFileGenerator</Generator>
-      <LastGenOutput>IBaseDal.cs</LastGenOutput>
-    </Content>
-    <Content Include="readme.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Models\Models.csproj">
-      <Project>{5400ca01-cbcf-4531-a388-3057393d5b4f}</Project>
-      <Name>Models</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>

+ 0 - 36
src/IDAL/Properties/AssemblyInfo.cs

@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的一般信息由以下
-// 控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("IDAL")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("IDAL")]
-[assembly: AssemblyCopyright("Copyright ©  2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 会使此程序集中的类型
-//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
-//请将此类型的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("7997fb01-c9c1-4793-a430-9ca3c3852b37")]
-
-// 程序集的版本信息由下列四个值组成: 
-//
-//      主版本
-//      次版本
-//      生成号
-//      修订号
-//
-// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
-//通过使用 "*",如下所示:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]

+ 0 - 5
src/IDAL/packages.config

@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="EFSecondLevelCache" version="1.2.0.0" targetFramework="net45" />
-  <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
-</packages>

+ 0 - 70
src/IDAL/readme.txt

@@ -1,70 +0,0 @@
-EFSecondLevelCache
-=======
-Entity Framework 6.x Second Level Caching Library.
-
-Second level caching is a query cache. The results of EF commands will be stored in the cache,
-so that the same EF commands will retrieve their data from the cache rather than executing them
-against the database again.
-
-
-Usage:
-1- Setting up the cache invalidation by overriding the SaveChanges method to prevent stale reads:
-
-namespace EFSecondLevelCache.TestDataLayer.DataLayer
-{
-	public class SampleContext : DbContext
-	{
-		// public DbSet<Product> Products { get; set; }
-
-		public SampleContext()
-			: base("connectionString1")
-		{
-		}
-
-		public override int SaveChanges()
-		{
-			return SaveAllChanges(invalidateCacheDependencies: true);
-		}
-
-		public int SaveAllChanges(bool invalidateCacheDependencies = true)
-		{
-			var changedEntityNames = getChangedEntityNames();
-			var result = base.SaveChanges();
-			if (invalidateCacheDependencies)
-			{
-				new EFCacheServiceProvider().InvalidateCacheDependencies(changedEntityNames);
-			}
-			return result;
-		}
-
-		private string[] getChangedEntityNames()
-		{
-			// Updated version of this method: \EFSecondLevelCache\EFSecondLevelCache.Tests\EFSecondLevelCache.TestDataLayer\DataLayer\SampleContext.cs
-			return this.ChangeTracker.Entries()
-				.Where(x => x.State == EntityState.Added ||
-							x.State == EntityState.Modified ||
-							x.State == EntityState.Deleted)
-				.Select(x => System.Data.Entity.Core.Objects.ObjectContext.GetObjectType(x.Entity.GetType()).FullName)
-				.Distinct()
-				.ToArray();
-		}
-	}
-}
-
-Sometimes you don't want to invalidate the cache when non important properties such as NumberOfViews are updated.
-In these cases, try SaveAllChanges(invalidateCacheDependencies: false), before updating the data.
-
-2- Then to cache the results of the normal queries like:
-var products = context.Products.Include(x => x.Tags).FirstOrDefault();
-
-We can use the new `Cacheable()` extension method:
-var products = context.Products.Include(x => x.Tags).Cacheable().FirstOrDefault(); // Async methods are supported too.
-
-
-Notes:
-Good candidates for query caching are global site's settings, list of public articles or comments
-and not frequently changed, private or specific data to each user.
-If a page requires authentication, its data shouldn't be cached.
-
-Project's Url:
-https://github.com/VahidN/EFSecondLevelCache

+ 37 - 0
src/Masuit.MyBlogs.Core.sln

@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.271
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masuit.Tools.Core", "..\Masuit.Tools\Masuit.Tools.Core\Masuit.Tools.Core.csproj", "{73B86CC2-A584-4B80-A627-689537F30DC3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masuit.MyBlogs.Core", "Masuit.MyBlogs.Core\Masuit.MyBlogs.Core.csproj", "{51A09BD3-AB54-4DF9-AB8B-C68DF0672C39}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masuit.HardwareMonitor.Dashboard", "Masuit.HardwareMonitor.Dashboard\Masuit.HardwareMonitor.Dashboard.csproj", "{EC5FA67A-56DC-42A7-9A03-777461D6DA11}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{73B86CC2-A584-4B80-A627-689537F30DC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{73B86CC2-A584-4B80-A627-689537F30DC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{73B86CC2-A584-4B80-A627-689537F30DC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{73B86CC2-A584-4B80-A627-689537F30DC3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{51A09BD3-AB54-4DF9-AB8B-C68DF0672C39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{51A09BD3-AB54-4DF9-AB8B-C68DF0672C39}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{51A09BD3-AB54-4DF9-AB8B-C68DF0672C39}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{51A09BD3-AB54-4DF9-AB8B-C68DF0672C39}.Release|Any CPU.Build.0 = Release|Any CPU
+		{EC5FA67A-56DC-42A7-9A03-777461D6DA11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{EC5FA67A-56DC-42A7-9A03-777461D6DA11}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{EC5FA67A-56DC-42A7-9A03-777461D6DA11}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{EC5FA67A-56DC-42A7-9A03-777461D6DA11}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {2D2DF884-78F6-45E0-80C5-25FAE9F0B5C9}
+	EndGlobalSection
+EndGlobal

+ 0 - 0
src/Masuit.MyBlogs.WebApp/App_Data/DenyIPRange.txt → src/Masuit.MyBlogs.Core/App_Data/DenyIPRange.txt


+ 0 - 0
src/Masuit.MyBlogs.WebApp/App_Data/ban.txt → src/Masuit.MyBlogs.Core/App_Data/ban.txt


+ 0 - 0
src/Masuit.MyBlogs.WebApp/App_Data/denyareaip.txt → src/Masuit.MyBlogs.Core/App_Data/denyareaip.txt


+ 0 - 0
src/Masuit.MyBlogs.WebApp/App_Data/denyip.txt → src/Masuit.MyBlogs.Core/App_Data/denyip.txt


+ 0 - 0
src/Masuit.MyBlogs.WebApp/App_Data/mod.txt → src/Masuit.MyBlogs.Core/App_Data/mod.txt


+ 0 - 0
src/Masuit.MyBlogs.WebApp/App_Data/whitelist.txt → src/Masuit.MyBlogs.Core/App_Data/whitelist.txt


+ 22 - 44
src/Common/CommonHelper.cs → src/Masuit.MyBlogs.Core/Common/CommonHelper.cs

@@ -5,17 +5,16 @@ using System.IO;
 using System.Linq;
 using System.Net.Http;
 using System.Net.Http.Headers;
-using EFSecondLevelCache;
 using Hangfire;
 using Masuit.Tools;
 using Masuit.Tools.Html;
 using Masuit.Tools.Media;
 #if !DEBUG
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.Tools.Models;
 #endif
 using Masuit.Tools.NoSQL;
 using Masuit.Tools.Security;
-using Models.Application;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 
@@ -28,11 +27,11 @@ namespace Common
     {
         static CommonHelper()
         {
-            BanRegex = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "ban.txt"));
-            ModRegex = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "mod.txt"));
-            DenyIP = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "denyip.txt"));
-            DenyAreaIP = JsonConvert.DeserializeObject<ConcurrentDictionary<string, HashSet<string>>>(File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "denyareaip.txt")));
-            string[] lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "DenyIPRange.txt"));
+            BanRegex = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "ban.txt"));
+            ModRegex = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "mod.txt"));
+            DenyIP = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "denyip.txt"));
+            DenyAreaIP = JsonConvert.DeserializeObject<ConcurrentDictionary<string, HashSet<string>>>(File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "denyareaip.txt")));
+            string[] lines = File.ReadAllLines(Path.Combine(AppContext.BaseDirectory + "App_Data", "DenyIPRange.txt"));
             DenyIPRange = new Dictionary<string, string>();
             foreach (string line in lines)
             {
@@ -46,7 +45,7 @@ namespace Common
                 }
             }
 
-            IPWhiteList = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "whitelist.txt")).Split(',', ',');
+            IPWhiteList = File.ReadAllText(Path.Combine(AppContext.BaseDirectory + "App_Data", "whitelist.txt")).Split(',', ',');
         }
 
         /// <summary>
@@ -79,6 +78,10 @@ namespace Common
         /// </summary>
         public static ConcurrentDictionary<string, int> IPErrorTimes { get; set; } = new ConcurrentDictionary<string, int>();
 
+        /// <summary>
+        /// 系统设定
+        /// </summary>
+        public static Dictionary<string, string> SystemSettings { get; set; }
         /// <summary>
         /// 访问量
         /// </summary>
@@ -131,27 +134,6 @@ namespace Common
         /// </summary>
         public static Dictionary<string, string> DenyIPRange { get; set; }
 
-        /// <summary>
-        /// 类型映射
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="source"></param>
-        /// <returns></returns>
-        public static T Mapper<T>(this object source) where T : class => AutoMapper.Mapper.Map<T>(source);
-
-        /// <summary>
-        /// 获取设置参数
-        /// </summary>
-        /// <param name="key"></param>
-        /// <returns></returns>
-        public static string GetSettings(string key)
-        {
-            using (var db = new DataContext())
-            {
-                return db.SystemSetting.Cacheable().FirstOrDefault(s => s.Name.Equals(key))?.Value;
-            }
-        }
-
         /// <summary>
         /// 判断IP地址是否被黑名单
         /// </summary>
@@ -167,17 +149,13 @@ namespace Common
             return DenyAreaIP.SelectMany(x => x.Value).Union(DenyIP.Split(',')).Contains(ip) || DenyIPRange.Any(kv => kv.Key.StartsWith(ip.Split('.')[0]) && ip.IpAddressInRange(kv.Key, kv.Value));
         }
 
-        #region 性能历史数据
-
-        public static List<object[]> HistoryCpuLoad { get; set; } = new List<object[]>();
-        public static List<object[]> HistoryMemoryUsage { get; set; } = new List<object[]>();
-        public static List<object[]> HistoryCpuTemp { get; set; } = new List<object[]>();
-        public static List<object[]> HistoryIORead { get; set; } = new List<object[]>();
-        public static List<object[]> HistoryIOWrite { get; set; } = new List<object[]>();
-        public static List<object[]> HistoryNetSend { get; set; } = new List<object[]>();
-        public static List<object[]> HistoryNetReceive { get; set; } = new List<object[]>();
-
-        #endregion
+        /// <summary>
+        /// 类型映射
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="source"></param>
+        /// <returns></returns>
+        public static T Mapper<T>(this object source) where T : class => AutoMapper.Mapper.Map<T>(source);
 
         /// <summary>
         /// 发送邮件
@@ -192,10 +170,10 @@ namespace Common
             {
                 EnableSsl = true,
                 Body = content,
-                SmtpServer = GetSettings("smtp"),
-                Username = GetSettings("EmailFrom"),
-                Password = GetSettings("EmailPwd"),
-                SmtpPort = GetSettings("SmtpPort").ToInt32(),
+                SmtpServer = EmailConfig.Smtp,
+                Username = EmailConfig.SendFrom,
+                Password = EmailConfig.EmailPwd,
+                SmtpPort = SystemSettings["SmtpPort"].ToInt32(),
                 Subject = title,
                 Tos = tos
             }.Send();

+ 3 - 3
src/Common/DocumentConvert.cs → src/Masuit.MyBlogs.Core/Common/DocumentConvert.cs

@@ -1,8 +1,8 @@
-using System.IO;
+using Aspose.Words;
+using System.IO;
 using System.Threading.Tasks;
-using Aspose.Words;
 
-namespace Common
+namespace Masuit.MyBlogs.Core.Common
 {
     /// <summary>
     /// 文档转换操作

+ 1 - 1
src/Common/HangfireHelper.cs → src/Masuit.MyBlogs.Core/Common/HangfireHelper.cs

@@ -3,7 +3,7 @@ using Hangfire.Common;
 using Hangfire.States;
 using System;
 
-namespace Common
+namespace Masuit.MyBlogs.Core.Common
 {
     public static class HangfireHelper
     {

+ 5 - 4
src/Common/RegisterAutomapper.cs → src/Masuit.MyBlogs.Core/Common/RegisterAutomapper.cs

@@ -1,10 +1,11 @@
 using AutoMapper;
-using Models.DTO;
-using Models.Entity;
-using Models.ViewModel;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using System.Linq;
 
-namespace Common
+namespace Masuit.MyBlogs.Core.Common
+
 {
     public static class RegisterAutomapper
     {

+ 9 - 0
src/Masuit.MyBlogs.Core/Configs/AppConfig.cs

@@ -0,0 +1,9 @@
+namespace Masuit.MyBlogs.Core.Configs
+{
+    public class AppConfig
+    {
+        public static string ConnString { get; set; }
+        public static string BaiduAK { get; set; }
+        public static string Redis { get; set; }
+    }
+}

+ 38 - 0
src/Masuit.MyBlogs.Core/Configs/HangfireJobInit.cs

@@ -0,0 +1,38 @@
+using Hangfire;
+using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Extensions.Hangfire;
+using Masuit.Tools;
+using Masuit.Tools.NoSQL;
+using System;
+
+namespace Masuit.MyBlogs.Core.Configs
+{
+    /// <summary>
+    /// hangfire配置
+    /// </summary>
+    public class HangfireJobInit
+    {
+        public static void Start()
+        {
+            RecurringJob.AddOrUpdate(() => CheckLinks(), Cron.HourInterval(5)); //每5h检查友链
+            RecurringJob.AddOrUpdate(() => EverydayJob(), Cron.Daily, TimeZoneInfo.Local); //每天的任务
+            using (RedisHelper redisHelper = RedisHelper.GetInstance())
+            {
+                if (!redisHelper.KeyExists("ArticleViewToken"))
+                {
+                    redisHelper.SetString("ArticleViewToken", string.Empty.CreateShortToken()); //更新加密文章的密码
+                }
+            }
+        }
+
+        public static void CheckLinks()
+        {
+            HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.CheckLinks), "default");
+        }
+
+        public static void EverydayJob()
+        {
+            HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.EverydayJob), "default");
+        }
+    }
+}

+ 120 - 0
src/Masuit.MyBlogs.Core/Configs/RegisterAutomapper.cs

@@ -0,0 +1,120 @@
+using AutoMapper;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Configs
+
+{
+    public static class RegisterAutomapper
+    {
+        public static void Excute()
+        {
+            Mapper.Initialize(m =>
+            {
+                m.CreateMap<Broadcast, BroadcastInputDto>();
+                m.CreateMap<BroadcastInputDto, Broadcast>();
+                m.CreateMap<Broadcast, BroadcastOutputDto>();
+                m.CreateMap<BroadcastOutputDto, Broadcast>();
+                m.CreateMap<BroadcastOutputDto, BroadcastInputDto>();
+                m.CreateMap<BroadcastInputDto, BroadcastOutputDto>();
+
+                m.CreateMap<Category, CategoryInputDto>();
+                m.CreateMap<CategoryInputDto, Category>();
+                m.CreateMap<Category, CategoryOutputDto>().ForMember(c => c.TotalPostCount, e => e.MapFrom(c => c.Post.Count)).ForMember(c => c.PendedPostCount, e => e.MapFrom(c => c.Post.Count(p => p.Status == Status.Pended)));
+                m.CreateMap<CategoryOutputDto, Category>();
+                m.CreateMap<CategoryInputDto, CategoryOutputDto>();
+                m.CreateMap<CategoryOutputDto, CategoryInputDto>();
+
+                m.CreateMap<Comment, CommentInputDto>();
+                m.CreateMap<CommentInputDto, Comment>();
+                m.CreateMap<Comment, CommentOutputDto>();
+                m.CreateMap<CommentOutputDto, Comment>();
+                m.CreateMap<CommentInputDto, CommentOutputDto>();
+                m.CreateMap<CommentOutputDto, CommentInputDto>();
+                m.CreateMap<Comment, CommentViewModel>().ForMember(c => c.CommentDate, e => e.MapFrom(c => c.CommentDate.ToString("yyyy-MM-dd HH:mm:ss")));
+
+                m.CreateMap<Contacts, ContactsInputDto>();
+                m.CreateMap<ContactsInputDto, Contacts>();
+                m.CreateMap<Contacts, ContactsOutputDto>();
+                m.CreateMap<ContactsOutputDto, Contacts>();
+                m.CreateMap<ContactsInputDto, ContactsOutputDto>();
+                m.CreateMap<ContactsOutputDto, ContactsInputDto>();
+
+                m.CreateMap<LeaveMessage, LeaveMessageInputDto>();
+                m.CreateMap<LeaveMessageInputDto, LeaveMessage>();
+                m.CreateMap<LeaveMessage, LeaveMessageOutputDto>();
+                m.CreateMap<LeaveMessageOutputDto, LeaveMessage>();
+                m.CreateMap<LeaveMessageInputDto, LeaveMessageOutputDto>();
+                m.CreateMap<LeaveMessageOutputDto, LeaveMessageInputDto>();
+                m.CreateMap<LeaveMessage, LeaveMessageViewModel>().ForMember(l => l.PostDate, e => e.MapFrom(l => l.PostDate.ToString("yyyy-MM-dd HH:mm:ss")));
+
+                m.CreateMap<Links, LinksInputDto>();
+                m.CreateMap<LinksInputDto, Links>();
+                m.CreateMap<Links, LinksOutputDto>();
+                m.CreateMap<LinksOutputDto, Links>();
+                m.CreateMap<LinksInputDto, LinksOutputDto>();
+                m.CreateMap<LinksOutputDto, LinksInputDto>();
+
+                m.CreateMap<Menu, MenuInputDto>();
+                m.CreateMap<MenuInputDto, Menu>();
+                m.CreateMap<Menu, MenuOutputDto>();
+                m.CreateMap<MenuOutputDto, Menu>();
+                m.CreateMap<MenuInputDto, MenuOutputDto>();
+                m.CreateMap<MenuOutputDto, MenuInputDto>();
+
+                m.CreateMap<Misc, MiscInputDto>();
+                m.CreateMap<MiscInputDto, Misc>();
+                m.CreateMap<Misc, MiscOutputDto>();
+                m.CreateMap<MiscOutputDto, Misc>();
+                m.CreateMap<MiscInputDto, MiscOutputDto>();
+                m.CreateMap<MiscOutputDto, MiscInputDto>();
+                m.CreateMap<Misc, MiscViewModel>().ForMember(c => c.PostDate, e => e.MapFrom(c => c.PostDate.ToString("yyyy-MM-dd HH:mm:ss"))).ForMember(c => c.ModifyDate, e => e.MapFrom(c => c.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")));
+
+                m.CreateMap<Notice, NoticeInputDto>();
+                m.CreateMap<NoticeInputDto, Notice>();
+                m.CreateMap<Notice, NoticeOutputDto>();
+                m.CreateMap<NoticeOutputDto, Notice>();
+                m.CreateMap<NoticeInputDto, NoticeOutputDto>();
+                m.CreateMap<NoticeOutputDto, NoticeInputDto>();
+                m.CreateMap<Notice, NoticeViewModel>().ForMember(c => c.PostDate, e => e.MapFrom(c => c.PostDate.ToString("yyyy-MM-dd HH:mm:ss"))).ForMember(c => c.ModifyDate, e => e.MapFrom(c => c.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")));
+
+                m.CreateMap<Post, PostInputDto>();
+                m.CreateMap<Post, PostHistoryVersion>().ForMember(v => v.PostId, e => e.MapFrom(p => p.Id));
+                m.CreateMap<PostInputDto, Post>();
+                m.CreateMap<Post, PostOutputDto>().ForMember(p => p.CategoryName, e => e.MapFrom(p => p.Category.Name)).ForMember(p => p.ViewCount, e => e.MapFrom(p => p.PostAccessRecord.Any() ? p.PostAccessRecord.Sum(r => r.ClickCount) : 0)).ForMember(p => p.AverageViewCount, e => e.MapFrom(p => p.PostAccessRecord.Any() ? p.PostAccessRecord.Average(r => r.ClickCount) : 0));
+                m.CreateMap<PostOutputDto, Post>();
+                m.CreateMap<PostInputDto, PostOutputDto>();
+                m.CreateMap<PostHistoryVersion, PostOutputDto>().ForMember(p => p.CategoryName, e => e.MapFrom(p => p.Category.Name));
+                m.CreateMap<PostOutputDto, PostInputDto>();
+                m.CreateMap<Post, PostViewModel>().ForMember(p => p.CategoryName, e => e.MapFrom(p => p.Category.Name)).ForMember(p => p.PostDate, e => e.MapFrom(p => p.PostDate.ToString("yyyy-MM-dd HH:mm:ss"))).ForMember(p => p.ModifyDate, e => e.MapFrom(p => p.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")));
+
+                m.CreateMap<SearchDetails, SearchDetailsInputDto>();
+                m.CreateMap<SearchDetailsInputDto, SearchDetails>();
+                m.CreateMap<SearchDetails, SearchDetailsOutputDto>();
+                m.CreateMap<SearchDetailsOutputDto, SearchDetails>();
+                m.CreateMap<SearchDetailsInputDto, SearchDetailsOutputDto>();
+                m.CreateMap<SearchDetailsOutputDto, SearchDetailsInputDto>();
+
+                m.CreateMap<UserInfo, UserInfoInputDto>();
+                m.CreateMap<UserInfoInputDto, UserInfo>();
+                m.CreateMap<UserInfo, UserInfoOutputDto>();
+                m.CreateMap<UserInfoOutputDto, UserInfo>();
+                m.CreateMap<UserInfoInputDto, UserInfoOutputDto>();
+                m.CreateMap<UserInfoOutputDto, UserInfoInputDto>();
+
+                m.CreateMap<LoginRecord, LoginRecordOutputDto>();
+                m.CreateMap<LoginRecordOutputDto, LoginRecord>();
+
+                m.CreateMap<Seminar, SeminarInputDto>();
+                m.CreateMap<SeminarInputDto, Seminar>();
+                m.CreateMap<Seminar, SeminarOutputDto>();
+                m.CreateMap<SeminarOutputDto, Seminar>();
+                m.CreateMap<SeminarInputDto, SeminarOutputDto>();
+                m.CreateMap<SeminarOutputDto, SeminarInputDto>();
+            });
+        }
+    }
+}

+ 11 - 26
src/Masuit.MyBlogs.WebApp/Controllers/AdminController.cs → src/Masuit.MyBlogs.Core/Controllers/AdminController.cs

@@ -1,20 +1,22 @@
-using System;
-using System.Text;
-using System.Web.Mvc;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
-using Models.ViewModel;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Microsoft.AspNetCore.Mvc;
 using Newtonsoft.Json;
+using System.Text;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
     /// <summary>
     /// 管理页的父控制器
     /// </summary>
-    [Authority, ValidateInput(false)]
+    [Authority, ApiExplorerSettings(IgnoreApi = true)]
     public class AdminController : Controller
     {
-        public IUserInfoBll UserInfoBll { get; set; }
+        /// <summary>
+        /// UserInfoService
+        /// </summary>
+        public IUserInfoService UserInfoService { get; set; }
 
         /// <summary>
         /// 返回结果json
@@ -54,22 +56,5 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 MissingMemberHandling = MissingMemberHandling.Ignore
             }), "application/json", Encoding.UTF8);
         }
-
-        /// <summary>创建 JsonResult 对象,该对象使用指定 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。</summary>
-        /// <returns>将指定对象序列化为 JSON 格式的结果对象。</returns>
-        /// <param name="data">要序列化的 JavaScript 对象图。</param>
-        /// <param name="behavior">JSON 请求行为。</param>
-        protected new JsonResult Json(object data, JsonRequestBehavior behavior)
-        {
-            return new JsonResult()
-            {
-                Data = data,
-                ContentType = "application/json",
-                ContentEncoding = Encoding.UTF8,
-                JsonRequestBehavior = behavior,
-                MaxJsonLength = Int32.MaxValue,
-                RecursionLimit = Int32.MaxValue
-            };
-        }
     }
 }

+ 59 - 51
src/Masuit.MyBlogs.WebApp/Controllers/BaseController.cs → src/Masuit.MyBlogs.Core/Controllers/BaseController.cs

@@ -1,36 +1,55 @@
-using System;
+using Masuit.MyBlogs.Core.Configs;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.NoSQL;
+using Masuit.Tools.Security;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Newtonsoft.Json;
+using System;
 using System.Collections.Generic;
-using System.Configuration;
 using System.Linq;
 using System.Net;
 using System.Text;
-using System.Web.Mvc;
-using Common;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
-using Masuit.Tools.Net;
-using Masuit.Tools.NoSQL;
-using Masuit.Tools.Security;
-using Models.DTO;
-using Models.Enum;
-using Models.ViewModel;
-using Newtonsoft.Json;
+#if DEBUG
+using Common; 
+#endif
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
     /// <summary>
     /// 基本父控制器
     /// </summary>
-    [MyExceptionFilter, MyActionFilter]
+    [ApiExplorerSettings(IgnoreApi = true)]
     public class BaseController : Controller
     {
-        public IUserInfoBll UserInfoBll { get; set; }
+        /// <summary>
+        /// UserInfoService
+        /// </summary>
+        public IUserInfoService UserInfoService { get; set; }
 
-        public IMenuBll MenuBll { get; set; }
+        /// <summary>
+        /// MenuService
+        /// </summary>
+        public IMenuService MenuService { get; set; }
 
-        public ILinksBll LinksBll { get; set; }
+        /// <summary>
+        /// LinksService
+        /// </summary>
+        public ILinksService LinksService { get; set; }
+
+        /// <summary>
+        /// ContactsService
+        /// </summary>
+        public IContactsService ContactsService { get; set; }
 
-        public IContactsBll ContactsBll { get; set; }
+        /// <summary>
+        /// RedisHelper
+        /// </summary>
         public RedisHelper RedisHelper { get; set; }
 
         /// <summary>
@@ -74,45 +93,34 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             }), "application/json", Encoding.UTF8);
         }
 
-        /// <summary>创建 JsonResult 对象,该对象使用指定 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。</summary>
-        /// <returns>将指定对象序列化为 JSON 格式的结果对象。</returns>
-        /// <param name="data">要序列化的 JavaScript 对象图。</param>
-        /// <param name="behavior">JSON 请求行为。</param>
-        protected new JsonResult Json(object data, JsonRequestBehavior behavior)
-        {
-            return new JsonResult()
-            {
-                Data = data,
-                ContentType = "application/json",
-                ContentEncoding = Encoding.UTF8,
-                JsonRequestBehavior = behavior,
-                MaxJsonLength = Int32.MaxValue,
-                RecursionLimit = Int32.MaxValue
-            };
-        }
-
         /// <summary>在调用操作方法前调用。</summary>
         /// <param name="filterContext">有关当前请求和操作的信息。</param>
-        protected override void OnActionExecuting(ActionExecutingContext filterContext)
+        public override void OnActionExecuting(ActionExecutingContext filterContext)
         {
             base.OnActionExecuting(filterContext);
-            if (filterContext.HttpContext.Request.HttpMethod.Equals("GET", StringComparison.InvariantCultureIgnoreCase)) //get方式的多半是页面
+            if (filterContext.HttpContext.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase)) //get方式的多半是页面
             {
                 UserInfoOutputDto user = filterContext.HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
 #if DEBUG
-                user = UserInfoBll.GetByUsername("masuit").Mapper<UserInfoOutputDto>();
-                Session.SetByRedis(SessionKey.UserInfo, user);
+                user = UserInfoService.GetByUsername("masuit").Mapper<UserInfoOutputDto>();
+                filterContext.HttpContext.Session.SetByRedis(SessionKey.UserInfo, user);
 #endif
                 if (user == null && Request.Cookies.Count > 2) //执行自动登录
                 {
-                    string name = CookieHelper.GetCookieValue("username");
-                    string pwd = CookieHelper.GetCookieValue("password")?.DesDecrypt(ConfigurationManager.AppSettings["BaiduAK"]);
-                    var userInfo = UserInfoBll.Login(name, pwd);
+                    string name = Request.Cookies["username"];
+                    string pwd = Request.Cookies["password"]?.DesDecrypt(AppConfig.BaiduAK);
+                    var userInfo = UserInfoService.Login(name, pwd);
                     if (userInfo != null)
                     {
-                        CookieHelper.SetCookie("username", name, DateTime.Now.AddDays(7));
-                        CookieHelper.SetCookie("password", CookieHelper.GetCookieValue("password"), DateTime.Now.AddDays(7));
-                        Session.SetByRedis(SessionKey.UserInfo, userInfo);
+                        Response.Cookies.Append("username", name, new CookieOptions()
+                        {
+                            Expires = DateTime.Now.AddDays(7)
+                        });
+                        Response.Cookies.Append("password", Request.Cookies["password"], new CookieOptions()
+                        {
+                            Expires = DateTime.Now.AddDays(7)
+                        });
+                        filterContext.HttpContext.Session.SetByRedis(SessionKey.UserInfo, userInfo);
                     }
                 }
             }
@@ -134,10 +142,10 @@ namespace Masuit.MyBlogs.WebApp.Controllers
 
         /// <summary>在调用操作方法后调用。</summary>
         /// <param name="filterContext">有关当前请求和操作的信息。</param>
-        protected override void OnActionExecuted(ActionExecutedContext filterContext)
+        public override void OnActionExecuted(ActionExecutedContext filterContext)
         {
             base.OnActionExecuted(filterContext);
-            if (filterContext.HttpContext.Request.HttpMethod.Equals("POST", StringComparison.InvariantCultureIgnoreCase) && filterContext.Result is ViewResult)
+            if (filterContext.HttpContext.Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase) && filterContext.Result is ViewResult)
             {
                 filterContext.Result = ResultData(null, false, "该URL仅支持Get请求方式", false, HttpStatusCode.MethodNotAllowed);
                 return;
@@ -145,11 +153,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
 
             #region 准备页面数据模型
 
-            ViewBag.menus = MenuBll.LoadEntitiesFromL2CacheNoTracking<MenuOutputDto>(m => m.Status == Status.Available).OrderBy(m => m.Sort).ToList(); //菜单
+            ViewBag.menus = MenuService.LoadEntitiesFromL2Cache<MenuOutputDto>(m => m.Status == Status.Available).OrderBy(m => m.Sort).ToList(); //菜单
             PageFootViewModel model = new PageFootViewModel //页脚
             {
-                Links = LinksBll.LoadPageEntitiesFromCacheNoTracking<object, LinksOutputDto>(1, 40, out int _, l => l.Status == Status.Available, l => new{l.Recommend,l.Id}, false, 1).ToList(),
-                Contacts = ContactsBll.LoadEntitiesFromL2CacheNoTracking<int, ContactsOutputDto>(l => l.Status == Status.Available, l => l.Id, false).ToList()
+                Links = LinksService.LoadPageEntities<bool, LinksOutputDto>(1, 40, out int _, l => l.Status == Status.Available, l => l.Recommend, false).ToList(),
+                Contacts = ContactsService.LoadEntities<int, ContactsOutputDto>(l => l.Status == Status.Available, l => l.Id, false).ToList()
             };
             ViewBag.Footer = model;
 

+ 181 - 0
src/Masuit.MyBlogs.Core/Controllers/BugController.cs

@@ -0,0 +1,181 @@
+using Common;
+using Hangfire;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.RequestModel;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Systems;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// bug反馈
+    /// </summary>
+    public class BugController : BaseController
+    {
+        /// <summary>
+        /// IssueService
+        /// </summary>
+        public IIssueService IssueService { get; set; }
+
+        /// <summary>
+        /// MessageService
+        /// </summary>
+        public IInternalMessageService MessageService { get; set; }
+
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// bug反馈
+        /// </summary>
+        /// <param name="issueService"></param>
+        /// <param name="messageService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public BugController(IIssueService issueService, IInternalMessageService messageService, IHostingEnvironment hostingEnvironment)
+        {
+            IssueService = issueService;
+            MessageService = messageService;
+            _hostingEnvironment = hostingEnvironment;
+        }
+
+        /// <summary>
+        /// bug首页
+        /// </summary>
+        /// <returns></returns>
+        [Route("bug")]
+        public ActionResult Index()
+        {
+            return View();
+        }
+
+        /// <summary>
+        /// 分页数据
+        /// </summary>
+        /// <param name="filter"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult PageData([FromBody]PageFilter filter)
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            List<Issue> list = string.IsNullOrEmpty(filter.Kw) ? IssueService.LoadPageEntitiesFromL2CacheNoTracking(filter.Page, filter.Size, out int total, i => i.Level != BugLevel.Fatal || user.IsAdmin, i => i.SubmitTime, false).ToList() : IssueService.SearchPage(filter.Page, filter.Size, out total, new[]
+            {
+                filter.Kw
+            }, i => (i.Level != BugLevel.Fatal || user.IsAdmin), i => i.SubmitTime, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / filter.Size).ToInt32();
+            return PageResult(list.Select(i => new
+            {
+                i.Id,
+                i.Name,
+                //i.Email,
+                i.Title,
+                i.Link,
+                i.Description,
+                i.SubmitTime,
+                i.HandleTime,
+                Status = i.Status.GetDisplay(),
+                Level = i.Level.GetDisplay()
+            }), pageCount, total);
+        }
+
+        /// <summary>
+        /// 问题详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Route("bug/{id:int}")]
+        public ActionResult Datails(int id)
+        {
+            Issue issue = IssueService.GetById(id);
+            if (issue is null)
+            {
+                return RedirectToAction("Index", "Error");
+            }
+            return View(issue);
+        }
+
+        /// <summary>
+        /// 处理
+        /// </summary>
+        /// <param name="id">问题id</param>
+        /// <param name="text">处理意见</param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Handle(int id, string text)
+        {
+            Issue issue = IssueService.GetById(id);
+            issue.Status = Status.Handled;
+            issue.HandleTime = DateTime.Now;
+            issue.Msg = text;
+            bool b = IssueService.UpdateEntitySaved(issue);
+            string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/bugfeed.html").Replace("{{title}}", issue.Title).Replace("{{link}}", issue.Link).Replace("{{text}}", text).Replace("{{date}}", issue.HandleTime.Value.ToString("yyyy-MM-dd HH:mm:ss"));
+            BackgroundJob.Enqueue(() => CommonHelper.SendMail("bug提交反馈通知", content, issue.Email));
+            return ResultData(null, b, b ? "问题处理成功!" : "处理失败!");
+        }
+
+        /// <summary>
+        /// 提交问题
+        /// </summary>
+        /// <param name="issue"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult Submit(Issue issue)
+        {
+            issue.Description = CommonHelper.ReplaceImgSrc(Regex.Replace(issue.Description, @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
+            issue.IPAddress = HttpContext.Connection.RemoteIpAddress.ToString();
+            Issue bug = IssueService.AddEntitySaved(issue);
+            if (bug != null)
+            {
+                MessageService.AddEntitySaved(new InternalMessage()
+                {
+                    Title = $"来自【{issue.Name}({issue.Email})】的bug问题反馈",
+                    Content = bug.Description,
+                    Link = Url.Action("Index")
+                });
+                string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/bugreport.html").Replace("{{name}}", bug.Name).Replace("{{email}}", bug.Email).Replace("{{title}}", bug.Title).Replace("{{desc}}", bug.Description).Replace("{{link}}", bug.Link).Replace("{{date}}", bug.SubmitTime.ToString("yyyy-MM-dd HH:mm:ss"));
+                BackgroundJob.Enqueue(() => CommonHelper.SendMail("bug提交通知", content, "[email protected]"));
+                return ResultData(issue, true, "问题提交成功,感谢您的反馈!");
+            }
+            return ResultData(null, false, "提交失败!");
+        }
+
+        /// <summary>
+        /// 删除问题
+        /// </summary>
+        /// <param name="id">问题id</param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Delete(int id)
+        {
+            bool b = IssueService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除成功!" : "删除失败!");
+        }
+
+        /// <summary>
+        /// 获取问题级别
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetBugLevels()
+        {
+            List<object> list = new List<object>();
+            foreach (Enum value in Enum.GetValues(typeof(BugLevel)))
+            {
+                list.Add(new
+                {
+                    name = value.GetDisplay(),
+                    value
+                });
+            }
+            return ResultData(list);
+        }
+    }
+}

+ 98 - 0
src/Masuit.MyBlogs.Core/Controllers/CategoryController.cs

@@ -0,0 +1,98 @@
+using Common;
+using EFSecondLevelCache.Core;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Microsoft.AspNetCore.Mvc;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 文章分类
+    /// </summary>
+    public class CategoryController : BaseController
+    {
+        /// <summary>
+        /// CategoryService
+        /// </summary>
+        public ICategoryService CategoryService { get; set; }
+
+        /// <summary>
+        /// 文章分类
+        /// </summary>
+        /// <param name="categoryService"></param>
+        public CategoryController(ICategoryService categoryService)
+        {
+            CategoryService = categoryService;
+        }
+
+        /// <summary>
+        /// 获取所有分类
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetCategories()
+        {
+            var list = CategoryService.LoadEntities<string, CategoryOutputDto>(c => c.Status == Status.Available, c => c.Name).Cacheable().ToList();
+            return ResultData(list);
+        }
+
+        /// <summary>
+        /// 获取分类详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public ActionResult Get(int id)
+        {
+            var model = CategoryService.GetById(id);
+            return ResultData(model.Mapper<CategoryOutputDto>());
+        }
+
+        /// <summary>
+        /// 添加分类
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        public ActionResult Add(Category model)
+        {
+            bool exist = CategoryService.Any(c => c.Name.Equals(model.Name));
+            if (exist)
+            {
+                return ResultData(null, false, $"分类{model.Name}已经存在!");
+            }
+            var cat = CategoryService.AddEntitySaved(model);
+            if (cat != null)
+            {
+                return ResultData(null, true, "分类添加成功!");
+            }
+            return ResultData(null, false, "分类添加失败!");
+        }
+
+        /// <summary>
+        /// 编辑分类
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public ActionResult Edit(CategoryInputDto dto)
+        {
+            Category cat = CategoryService.GetById(dto.Id);
+            cat.Name = dto.Name;
+            cat.Description = dto.Description;
+            bool b = CategoryService.UpdateEntitySaved(cat);
+            return ResultData(null, b, b ? "分类修改成功!" : "分类修改失败!");
+        }
+
+        /// <summary>
+        /// 删除分类
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="cid"></param>
+        /// <returns></returns>
+        public ActionResult Delete(int id, int cid = 1)
+        {
+            bool b = CategoryService.Delete(id, cid);
+            return ResultData(null, b, b ? "分类删除成功" : "分类删除失败");
+        }
+    }
+}

+ 340 - 0
src/Masuit.MyBlogs.Core/Controllers/CommentController.cs

@@ -0,0 +1,340 @@
+using Common;
+using Hangfire;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Html;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Net.Http.Headers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 评论管理
+    /// </summary>
+    public class CommentController : BaseController
+    {
+        private ICommentService CommentService { get; }
+        private IPostService PostService { get; }
+        private IInternalMessageService MessageService { get; }
+        private readonly IHostingEnvironment _hostingEnvironment;
+        /// <summary>
+        /// 评论管理
+        /// </summary>
+        /// <param name="commentService"></param>
+        /// <param name="postService"></param>
+        /// <param name="messageService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public CommentController(ICommentService commentService, IPostService postService, IInternalMessageService messageService, IHostingEnvironment hostingEnvironment)
+        {
+            CommentService = commentService;
+            PostService = postService;
+            MessageService = messageService;
+            _hostingEnvironment = hostingEnvironment;
+        }
+
+        /// <summary>
+        /// 发表评论
+        /// </summary>
+        /// <param name="comment"></param>
+        /// <returns></returns>
+        [HttpPost, ValidateAntiForgeryToken]
+        public ActionResult Put(CommentInputDto comment)
+        {
+            Post post = PostService.GetById(comment.PostId);
+            if (post is null)
+            {
+                return ResultData(null, false, "评论失败,文章不存在!");
+            }
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            comment.Content = comment.Content.Trim().Replace("<p><br></p>", string.Empty);
+
+            if (comment.Content.RemoveHtml().Trim().Equals(HttpContext.Session.GetByRedis<string>("comment" + comment.PostId)))
+            {
+                return ResultData(null, false, "您刚才已经在这篇文章发表过一次评论了,换一篇文章吧,或者换一下评论内容吧!");
+            }
+            if (Regex.Match(comment.Content, CommonHelper.ModRegex).Length <= 0)
+            {
+                comment.Status = Status.Pended;
+            }
+            if (user != null)
+            {
+                comment.NickName = user.NickName;
+                comment.QQorWechat = user.QQorWechat;
+                comment.Email = user.Email;
+                if (user.IsAdmin)
+                {
+                    comment.Status = Status.Pended;
+                    comment.IsMaster = true;
+                }
+            }
+            comment.Content = Regex.Replace(comment.Content.HtmlSantinizerStandard().ConvertImgSrcToRelativePath(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>");
+            comment.CommentDate = DateTime.Now;
+            comment.Browser = comment.Browser ?? Request.Headers[HeaderNames.UserAgent];
+            comment.IP = HttpContext.Connection.RemoteIpAddress.ToString();
+            Comment com = CommentService.AddEntitySaved(comment.Mapper<Comment>());
+            if (com != null)
+            {
+                HttpContext.Session.SetByRedis("comment" + comment.PostId, comment.Content.RemoveHtml().Trim());
+                var emails = new List<string>();
+                var email = CommonHelper.SystemSettings["ReceiveEmail"]; //站长邮箱
+                emails.Add(email);
+                string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/notify.html").Replace("{{title}}", post.Title).Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{nickname}}", com.NickName).Replace("{{content}}", com.Content);
+                if (comment.Status == Status.Pended)
+                {
+                    if (!com.IsMaster)
+                    {
+                        MessageService.AddEntitySaved(new InternalMessage()
+                        {
+                            Title = $"来自【{com.NickName}】的新文章评论",
+                            Content = com.Content,
+                            Link = Url.Action("Details", "Post", new
+                            {
+                                id = com.PostId,
+                                cid = com.Id
+                            }, Request.Scheme) + "#comment"
+                        });
+                    }
+#if !DEBUG
+                    if (com.ParentId == 0)
+                    {
+                        emails.Add(PostService.GetById(com.PostId).Email);
+                        //新评论,只通知博主和楼主
+                        foreach (var s in emails.Distinct())
+                        {
+                            BackgroundJob.Enqueue(() => CommonHelper.SendMail(Request.Host + "|博客文章新评论:", content.Replace("{{link}}", Url.Action("Details", "Post", new
+                            {
+                                id = com.PostId,
+                                cid = com.Id
+                            }, Request.Scheme) + "#comment"), s));
+                        }
+                    }
+                    else
+                    {
+                        //通知博主和上层所有关联的评论访客
+                        var pid = CommentService.GetParentCommentIdByChildId(com.Id);
+                        emails = CommentService.GetSelfAndAllChildrenCommentsByParentId(pid).Select(c => c.Email).Except(new List<string>()
+                        {
+                            com.Email
+                        }).Distinct().ToList();
+                        string link = Url.Action("Details", "Post", new
+                        {
+                            id = com.PostId,
+                            cid = com.Id
+                        }, Request.Scheme) + "#comment";
+                        foreach (var s in emails)
+                        {
+                            BackgroundJob.Enqueue(() => CommonHelper.SendMail($"{Request.Host}{CommonHelper.SystemSettings["Title"]}文章评论回复:", content.Replace("{{link}}", link), s));
+                        }
+                    }
+#endif
+                    return ResultData(null, true, "评论发表成功,服务器正在后台处理中,这会有一定的延迟,稍后将显示到评论列表中");
+                }
+                foreach (var s in emails.Distinct())
+                {
+
+                    BackgroundJob.Enqueue(() => CommonHelper.SendMail(Request.Host + Request.Path + "|博客文章新评论(待审核):", content.Replace("{{link}}", Url.Action("Details", "Post", new
+                    {
+                        id = com.PostId,
+                        cid = com.Id
+                    }, Request.Scheme) + "#comment") + "<p style='color:red;'>(待审核)</p>", s));
+                }
+                return ResultData(null, true, "评论成功,待站长审核通过以后将显示");
+            }
+            return ResultData(null, false, "评论失败");
+        }
+
+        /// <summary>
+        /// 评论投票
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult CommentVote(int id)
+        {
+            Comment cm = CommentService.GetFirstEntity(c => c.Id == id && c.Status == Status.Pended);
+            if (HttpContext.Session.Get<object>("cm" + id) != null)
+            {
+                return ResultData(null, false, "您刚才已经投过票了,感谢您的参与!");
+            }
+            if (cm != null)
+            {
+                cm.VoteCount++;
+                CommentService.UpdateEntity(cm);
+                HttpContext.Session.Set("cm" + id, id);
+                bool b = CommentService.SaveChanges() > 0;
+                return ResultData(null, b, b ? "投票成功" : "投票失败");
+            }
+            return ResultData(null, false, "非法操作");
+        }
+
+        /// <summary>
+        /// 获取评论
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="cid"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult GetComments(int? id, int page = 1, int size = 5, int cid = 0)
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            int total; //总条数,用于前台分页
+            if (cid != 0)
+            {
+                int pid = CommentService.GetParentCommentIdByChildId(cid);
+                List<Comment> single = CommentService.GetSelfAndAllChildrenCommentsByParentId(pid).ToList();
+                if (single.Any())
+                {
+                    total = 1;
+                    return ResultData(new
+                    {
+                        total,
+                        parentTotal = total,
+                        page,
+                        size,
+                        rows = single.Mapper<IList<CommentViewModel>>()
+                    });
+                }
+            }
+            IList<Comment> parent = CommentService.LoadPageEntities(page, size, out total, c => c.PostId == id && c.ParentId == 0 && (c.Status == Status.Pended || user.IsAdmin), c => c.CommentDate, false).ToList();
+            if (!parent.Any())
+            {
+                return ResultData(null, false, "没有评论");
+            }
+            var list = new List<Comment>();
+            parent.ForEach(c => CommentService.GetSelfAndAllChildrenCommentsByParentId(c.Id).ForEach(result => list.Add(result)));
+            var qlist = list.Where(c => (c.Status == Status.Pended || user.IsAdmin));
+            if (total > 0)
+            {
+                return ResultData(new
+                {
+                    total,
+                    parentTotal = total,
+                    page,
+                    size,
+                    rows = qlist.Mapper<IList<CommentViewModel>>()
+                });
+            }
+            return ResultData(null, false, "没有评论");
+        }
+
+        /// <summary>
+        /// 分页获取评论
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="cid"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult GetPageComments(int page = 1, int size = 5, int cid = 0)
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            int total; //总条数,用于前台分页
+            if (cid != 0)
+            {
+                int pid = CommentService.GetParentCommentIdByChildId(cid);
+                List<Comment> single = CommentService.GetSelfAndAllChildrenCommentsByParentId(pid).ToList();
+                if (single.Any())
+                {
+                    total = 1;
+                    return ResultData(new
+                    {
+                        total,
+                        parentTotal = total,
+                        page,
+                        size,
+                        rows = single.Mapper<IList<CommentViewModel>>()
+                    });
+                }
+            }
+            IList<Comment> parent = CommentService.LoadPageEntities(page, size, out total, c => c.ParentId == 0 && (c.Status == Status.Pended || user.IsAdmin), c => c.CommentDate, false).ToList();
+            if (!parent.Any())
+            {
+                return ResultData(null, false, "没有评论");
+            }
+            var list = new List<Comment>();
+            parent.ForEach(c => CommentService.GetSelfAndAllChildrenCommentsByParentId(c.Id).ForEach(result => list.Add(result)));
+            var qlist = list.Where(c => (c.Status == Status.Pended || user.IsAdmin));
+            if (total > 0)
+            {
+                return ResultData(new
+                {
+                    total,
+                    parentTotal = total,
+                    page,
+                    size,
+                    rows = qlist.Mapper<IList<CommentViewModel>>()
+                });
+            }
+            return ResultData(null, false, "没有评论");
+        }
+
+        /// <summary>
+        /// 审核评论
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Pass(int id)
+        {
+            Comment comment = CommentService.GetById(id);
+            comment.Status = Status.Pended;
+            Post post = PostService.GetById(comment.PostId);
+            bool b = CommentService.UpdateEntitySaved(comment);
+            var pid = comment.ParentId == 0 ? comment.Id : CommentService.GetParentCommentIdByChildId(id);
+#if !DEBUG
+            string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + ("template/notify.html")).Replace("{{title}}", post.Title).Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{nickname}}", comment.NickName).Replace("{{content}}", comment.Content);
+            var emails = CommentService.GetSelfAndAllChildrenCommentsByParentId(pid).Select(c => c.Email).Distinct().Except(new List<string>()
+            {
+                comment.Email,
+                CommonHelper.SystemSettings["ReceiveEmail"]
+            }).ToList();
+            string link = Url.Action("Details", "Post", new
+            {
+                id = comment.PostId,
+                cid = pid
+            }, Request.Scheme) + "#comment";
+            foreach (var email in emails)
+            {
+                BackgroundJob.Enqueue(() => CommonHelper.SendMail($"{Request.Host}{CommonHelper.SystemSettings["Title"]}文章评论回复:", content.Replace("{{link}}", link), email));
+            }
+#endif
+            return ResultData(null, b, b ? "审核通过!" : "审核失败!");
+        }
+
+        /// <summary>
+        /// 删除评论
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Delete(int id)
+        {
+            var b = CommentService.DeleteEntitiesSaved(CommentService.GetSelfAndAllChildrenCommentsByParentId(id).ToList());
+            return ResultData(null, b, b ? "删除成功!" : "删除失败!");
+        }
+
+        /// <summary>
+        /// 获取未审核的评论
+        /// </summary>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult GetPendingComments(int page = 1, int size = 10)
+        {
+            List<CommentOutputDto> list = CommentService.LoadPageEntities<DateTime, CommentOutputDto>(page, size, out int total, c => c.Status == Status.Pending, c => c.CommentDate, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+    }
+}

+ 77 - 0
src/Masuit.MyBlogs.Core/Controllers/ContactController.cs

@@ -0,0 +1,77 @@
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 联系方式管理
+    /// </summary>
+    public class ContactController : AdminController
+    {
+        /// <summary>
+        /// ContactService
+        /// </summary>
+        public IContactsService ContactService { get; set; }
+
+        /// <summary>
+        /// 联系方式管理
+        /// </summary>
+        /// <param name="contactsService"></param>
+        public ContactController(IContactsService contactsService)
+        {
+            ContactService = contactsService;
+        }
+
+        /// <summary>
+        /// 添加联系方式
+        /// </summary>
+        /// <param name="links"></param>
+        /// <returns></returns>
+        public ActionResult Add(Contacts links)
+        {
+            var e = ContactService.AddEntitySaved(links);
+            return e != null ? ResultData(null, message: "添加成功!") : ResultData(null, false, "添加失败!");
+        }
+
+        /// <summary>
+        /// 删除联系方式
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public ActionResult Delete(int id)
+        {
+            bool b = ContactService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除成功!" : "删除失败!");
+        }
+
+        /// <summary>
+        /// 编辑联系方式
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        public ActionResult Edit(Contacts model)
+        {
+            var contacts = ContactService.GetById(model.Id);
+            contacts.Title = model.Title;
+            contacts.Url = model.Url;
+            bool b = ContactService.UpdateEntitySaved(contacts);
+            return ResultData(null, b, b ? "保存成功" : "保存失败");
+        }
+
+        /// <summary>
+        /// 分页数据
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        public ActionResult GetPageData(int page = 1, int size = 10)
+        {
+            var list = ContactService.LoadPageEntitiesNoTracking(page, size, out int total, l => true, l => l.Id, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+    }
+}

+ 141 - 0
src/Masuit.MyBlogs.Core/Controllers/DashboardController.cs

@@ -0,0 +1,141 @@
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.Tools.Logging;
+using Microsoft.AspNetCore.Mvc;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 控制面板
+    /// </summary>
+    public class DashboardController : AdminController
+    {
+        /// <summary>
+        /// PostService
+        /// </summary>
+        public IPostService PostService { get; set; }
+        /// <summary>
+        /// LeaveMessageService
+        /// </summary>
+        public ILeaveMessageService LeaveMessageService { get; set; }
+        /// <summary>
+        /// CommentService
+        /// </summary>
+        public ICommentService CommentService { get; set; }
+
+        /// <summary>
+        /// 控制面板
+        /// </summary>
+        /// <param name="userInfoService"></param>
+        /// <param name="postService"></param>
+        /// <param name="commentService"></param>
+        /// <param name="leaveMessageService"></param>
+        public DashboardController(IUserInfoService userInfoService, IPostService postService, ICommentService commentService, ILeaveMessageService leaveMessageService)
+        {
+            UserInfoService = userInfoService;
+            CommentService = commentService;
+            LeaveMessageService = leaveMessageService;
+            PostService = postService;
+        }
+
+        /// <summary>
+        /// 控制面板
+        /// </summary>
+        /// <returns></returns>
+        [Route("dashboard")]
+        public ActionResult Index()
+        {
+            return View();
+        }
+
+        /// <summary>
+        /// 获取站内消息
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetMessages()
+        {
+            var post = PostService.LoadEntitiesFromL2CacheNoTracking(p => p.Status == Status.Pending).Select(p => new
+            {
+                p.Id,
+                p.Title,
+                p.PostDate,
+                p.Author
+            });
+            var msgs = LeaveMessageService.LoadEntitiesFromL2CacheNoTracking(m => m.Status == Status.Pending).Select(p => new
+            {
+                p.Id,
+                p.PostDate,
+                p.NickName
+            });
+            var comments = CommentService.LoadEntitiesFromL2CacheNoTracking(c => c.Status == Status.Pending).Select(p => new
+            {
+                p.Id,
+                p.CommentDate,
+                p.PostId,
+                p.NickName
+            });
+            return ResultData(new
+            {
+                post,
+                msgs,
+                comments
+            });
+        }
+
+        /// <summary>
+        /// 获取日志文件列表
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetLogfiles()
+        {
+            List<string> files = Directory.GetFiles(LogManager.LogDirectory).OrderByDescending(s => s).Select(Path.GetFileName).ToList();
+            return ResultData(files);
+        }
+
+        /// <summary>
+        /// 查看日志
+        /// </summary>
+        /// <param name="filename"></param>
+        /// <returns></returns>
+        public ActionResult Catlog(string filename)
+        {
+            if (System.IO.File.Exists(Path.Combine(LogManager.LogDirectory, filename)))
+            {
+                string text = System.IO.File.ReadAllText(Path.Combine(LogManager.LogDirectory, filename));
+                return ResultData(text);
+            }
+            return ResultData(null, false, "文件不存在!");
+        }
+
+        /// <summary>
+        /// 删除文件
+        /// </summary>
+        /// <param name="filename"></param>
+        /// <returns></returns>
+        public ActionResult DeleteFile(string filename)
+        {
+            try
+            {
+                System.IO.File.Delete(Path.Combine(LogManager.LogDirectory, filename));
+                return ResultData(null, message: "文件删除成功!");
+            }
+            catch (IOException)
+            {
+                return ResultData(null, false, "文件删除失败!");
+            }
+        }
+
+        /// <summary>
+        /// 资源管理器
+        /// </summary>
+        /// <returns></returns>
+        [Route("filemanager")]
+        public ActionResult FileManager()
+        {
+            return View();
+        }
+    }
+}

+ 91 - 0
src/Masuit.MyBlogs.Core/Controllers/DonateController.cs

@@ -0,0 +1,91 @@
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 捐赠管理
+    /// </summary>
+    public class DonateController : AdminController
+    {
+        /// <summary>
+        /// DonateService
+        /// </summary>
+        public IDonateService DonateService { get; set; }
+
+        /// <summary>
+        /// 捐赠管理
+        /// </summary>
+        /// <param name="donateService"></param>
+        public DonateController(IDonateService donateService)
+        {
+            DonateService = donateService;
+        }
+
+        /// <summary>
+        /// 分页数据
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        public ActionResult GetPageData(int page = 1, int size = 10)
+        {
+            var list = DonateService.LoadPageEntitiesFromL2CacheNoTracking(page, size, out int total, d => true, d => d.DonateTime, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public ActionResult Get(int id)
+        {
+            Donate donate = DonateService.GetById(id);
+            return ResultData(donate);
+        }
+
+        /// <summary>
+        /// 保存数据
+        /// </summary>
+        /// <param name="donate"></param>
+        /// <returns></returns>
+        public ActionResult Save(Donate donate)
+        {
+            var entry = DonateService.GetById(donate.Id);
+            bool b;
+            if (entry is null)
+            {
+                b = DonateService.AddEntitySaved(donate) != null;
+            }
+            else
+            {
+                entry.NickName = donate.NickName;
+                entry.Amount = donate.Amount;
+                entry.DonateTime = donate.DonateTime;
+                entry.Email = donate.Email;
+                entry.EmailDisplay = donate.EmailDisplay;
+                entry.QQorWechat = donate.QQorWechat;
+                entry.QQorWechatDisplay = donate.QQorWechatDisplay;
+                entry.Via = donate.Via;
+                b = DonateService.UpdateEntitySaved(entry);
+            }
+            return ResultData(null, b, b ? "保存成功!" : "保存失败!");
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public ActionResult Delete(int id)
+        {
+            bool b = DonateService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除成功!" : "删除失败!");
+        }
+    }
+}

+ 18 - 6
src/Masuit.MyBlogs.WebApp/Controllers/ErrorController.cs → src/Masuit.MyBlogs.Core/Controllers/ErrorController.cs

@@ -1,14 +1,22 @@
-using System.Web.Mvc;
+using Microsoft.AspNetCore.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 错误页
+    /// </summary>
+    [ApiExplorerSettings(IgnoreApi = true)]
     public class ErrorController : Controller
     {
+        /// <summary>
+        /// 404
+        /// </summary>
+        /// <returns></returns>
         [Route("error")]
         public ActionResult Index()
         {
             //Response.StatusCode = 404;
-            if (Request.HttpMethod.ToLower().Equals("get"))
+            if (Request.Method.ToLower().Equals("get"))
             {
                 return View();
             }
@@ -17,14 +25,18 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 StatusCode = 404,
                 Success = false,
                 Message = "页面未找到!"
-            }, JsonRequestBehavior.AllowGet);
+            });
         }
 
+        /// <summary>
+        /// 503
+        /// </summary>
+        /// <returns></returns>
         [Route("ServiceUnavailable")]
         public ActionResult ServiceUnavailable()
         {
             //Response.StatusCode = 503;
-            if (Request.HttpMethod.ToLower().Equals("get"))
+            if (Request.Method.ToLower().Equals("get"))
             {
                 return View();
             }
@@ -33,7 +45,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 StatusCode = 503,
                 Success = false,
                 Message = "服务器发生错误!"
-            }, JsonRequestBehavior.AllowGet);
+            });
         }
     }
 }

+ 91 - 44
src/Masuit.MyBlogs.WebApp/Controllers/FileController.cs → src/Masuit.MyBlogs.Core/Controllers/FileController.cs

@@ -1,23 +1,45 @@
 using Common;
-using Masuit.MyBlogs.WebApp.Models;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
 using Masuit.Tools.Files;
 using Masuit.Tools.Logging;
-using Masuit.Tools.Mvc;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
-using System.Web.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 资源管理器
+    /// </summary>
+    [Route("[controller]/[action]")]
     public class FileController : AdminController
     {
-        public List<string> FileList { get; set; } = new List<string>();
+        private readonly IHostingEnvironment _hostingEnvironment;
+        private readonly ISevenZipCompressor _sevenZipCompressor;
 
+        /// <summary>
+        /// 资源管理器
+        /// </summary>
+        /// <param name="hostingEnvironment"></param>
+        /// <param name="sevenZipCompressor"></param>
+        public FileController(IHostingEnvironment hostingEnvironment, ISevenZipCompressor sevenZipCompressor)
+        {
+            _hostingEnvironment = hostingEnvironment;
+            _sevenZipCompressor = sevenZipCompressor;
+        }
+
+        /// <summary>
+        /// 获取文件列表
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
         public ActionResult GetFiles(string path)
         {
-            var files = Directory.GetFiles(Request.MapPath(path)).OrderByDescending(s => s).Select(s => new
+            var files = Directory.GetFiles(_hostingEnvironment.WebRootPath + path).OrderByDescending(s => s).Select(s => new
             {
                 filename = Path.GetFileName(s),
                 path = s
@@ -25,6 +47,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(files);
         }
 
+        /// <summary>
+        /// 读取文件内容
+        /// </summary>
+        /// <param name="filename"></param>
+        /// <returns></returns>
         public ActionResult Read(string filename)
         {
             if (System.IO.File.Exists(filename))
@@ -35,7 +62,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null, false, "文件不存在!");
         }
 
-        [ValidateInput(false)]
+        /// <summary>
+        /// 保存文件
+        /// </summary>
+        /// <param name="filename"></param>
+        /// <param name="content"></param>
+        /// <returns></returns>
         public ActionResult Save(string filename, string content)
         {
             try
@@ -50,15 +82,20 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             }
         }
 
+        /// <summary>
+        /// 操作文件
+        /// </summary>
+        /// <param name="req"></param>
+        /// <returns></returns>
         [HttpPost]
-        public ActionResult Handle(FileRequest req)
+        public ActionResult Handle([FromBody]FileRequest req)
         {
             List<object> list = new List<object>();
-            var prefix = CommonHelper.GetSettings("PathRoot").Trim('\\', '/');
+            var prefix = CommonHelper.SystemSettings["PathRoot"].Trim('\\', '/');
             switch (req.Action)
             {
                 case "list":
-                    string path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Path) : prefix + req.Path; //Server.MapPath(req.Path);
+                    string path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + req.Path : prefix + req.Path; //_hostingEnvironment.WebRootPath + (req.Path);
                     string[] dirs = Directory.GetDirectories(path);
                     string[] files = Directory.GetFiles(path);
                     dirs.ForEach(s =>
@@ -89,7 +126,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 case "remove":
                     req.Items.ForEach(s =>
                     {
-                        s = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(s) : prefix + s;
+                        s = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + s : prefix + s;
                         try
                         {
                             System.IO.File.Delete(s);
@@ -106,8 +143,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     break;
                 case "rename":
                 case "move":
-                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Item) : prefix + req.Item;
-                    var newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.NewItemPath) : prefix + req.NewItemPath;
+                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + req.Item : prefix + req.Item;
+                    var newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + req.NewItemPath : prefix + req.NewItemPath;
                     if (!string.IsNullOrEmpty(req.Item))
                     {
                         try
@@ -121,16 +158,16 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     }
                     else
                     {
-                        newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.NewPath) : prefix + req.NewPath;
+                        newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + req.NewPath : prefix + req.NewPath;
                         req.Items.ForEach(s =>
                         {
                             try
                             {
-                                System.IO.File.Move(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(s) : prefix + s, Path.Combine(newpath, Path.GetFileName(s)));
+                                System.IO.File.Move(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (s) : prefix + s, Path.Combine(newpath, Path.GetFileName(s)));
                             }
                             catch
                             {
-                                Directory.Move(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(s) : prefix + s, Path.Combine(newpath, Path.GetFileName(s)));
+                                Directory.Move(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (s) : prefix + s, Path.Combine(newpath, Path.GetFileName(s)));
                             }
                         });
                     }
@@ -140,18 +177,18 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     });
                     break;
                 case "copy":
-                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Item) : prefix + req.Item;
-                    newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.NewItemPath) : prefix + req.NewItemPath;
-                    //newpath = Server.MapPath(req.NewItemPath);
+                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Item) : prefix + req.Item;
+                    newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.NewItemPath) : prefix + req.NewItemPath;
+                    //newpath = _hostingEnvironment.WebRootPath + (req.NewItemPath);
                     if (!string.IsNullOrEmpty(req.Item))
                     {
                         System.IO.File.Copy(path, newpath);
                     }
                     else
                     {
-                        newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.NewPath) : prefix + req.NewPath;
-                        //Server.MapPath(req.NewPath);
-                        req.Items.ForEach(s => System.IO.File.Copy(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(s) : prefix + s, !string.IsNullOrEmpty(req.SingleFilename) ? Path.Combine(newpath, req.SingleFilename) : Path.Combine(newpath, Path.GetFileName(s))));
+                        newpath = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.NewPath) : prefix + req.NewPath;
+                        //_hostingEnvironment.WebRootPath + (req.NewPath);
+                        req.Items.ForEach(s => System.IO.File.Copy(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (s) : prefix + s, !string.IsNullOrEmpty(req.SingleFilename) ? Path.Combine(newpath, req.SingleFilename) : Path.Combine(newpath, Path.GetFileName(s))));
                     }
                     list.Add(new
                     {
@@ -159,8 +196,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     });
                     break;
                 case "edit":
-                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Item) : prefix + req.Item;
-                    //path = Server.MapPath(req.Item);
+                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Item) : prefix + req.Item;
+                    //path = _hostingEnvironment.WebRootPath + (req.Item);
                     string content = req.Content;
                     System.IO.File.WriteAllText(path, content, Encoding.UTF8);
                     list.Add(new
@@ -169,16 +206,16 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     });
                     break;
                 case "getContent":
-                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Item) : prefix + req.Item;
-                    //path = Server.MapPath(req.Item);
+                    path = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Item) : prefix + req.Item;
+                    //path = _hostingEnvironment.WebRootPath + (req.Item);
                     content = System.IO.File.ReadAllText(path, Encoding.UTF8);
                     return Json(new
                     {
                         result = content
-                    }, JsonRequestBehavior.AllowGet);
+                    });
                 case "createFolder":
-                    string dir = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.NewPath) : prefix + req.NewPath;
-                    //string dir = Server.MapPath(req.NewPath);
+                    string dir = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.NewPath) : prefix + req.NewPath;
+                    //string dir = _hostingEnvironment.WebRootPath + (req.NewPath);
                     var directoryInfo = Directory.CreateDirectory(dir);
                     list.Add(new
                     {
@@ -188,8 +225,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 case "changePermissions":
                     break;
                 case "compress":
-                    string filename = Path.Combine(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Destination) : prefix + req.Destination, Path.GetFileNameWithoutExtension(req.CompressedFilename) + ".zip");
-                    SevenZipCompressor.Zip(req.Items.Select(s => string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(s) : prefix + s).ToList(), filename);
+                    string filename = Path.Combine(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Destination) : prefix + req.Destination, Path.GetFileNameWithoutExtension(req.CompressedFilename) + ".zip");
+                    _sevenZipCompressor.Zip(req.Items.Select(s => string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (s) : prefix + s).ToList(), filename);
 
                     list.Add(new
                     {
@@ -197,22 +234,25 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     });
                     break;
                 case "extract":
-                    string folder = Path.Combine(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Destination) : prefix + req.Destination, req.FolderName.Trim('/', '\\'));
-                    string zip = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Item) : prefix + req.Item;
-                    SevenZipCompressor.Extract(zip, folder);
+                    string folder = Path.Combine(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Destination) : prefix + req.Destination, req.FolderName.Trim('/', '\\'));
+                    string zip = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Item) : prefix + req.Item;
+                    _sevenZipCompressor.Extract(zip, folder);
                     list.Add(new
                     {
                         success = "true"
                     });
                     break;
                 default:
-                    var httpfiles = Request.Files;
+                    var httpfiles = Request.Form.Files;
                     if (httpfiles.Count > 0)
                     {
-                        for (var i = 0; i < httpfiles.Count; i++)
+                        foreach (var t in httpfiles)
                         {
-                            path = Path.Combine(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(req.Destination) : prefix + req.Destination, httpfiles[i].FileName);
-                            httpfiles[i].SaveAs(path);
+                            path = Path.Combine(string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (req.Destination) : prefix + req.Destination, t.FileName);
+                            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
+                            {
+                                t.CopyTo(fs);
+                            }
                         }
                     }
                     break;
@@ -220,25 +260,32 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return Json(new
             {
                 result = list
-            }, JsonRequestBehavior.AllowGet);
+            });
         }
 
+        /// <summary>
+        /// 下载文件
+        /// </summary>
+        /// <param name="path"></param>
+        /// <param name="items"></param>
+        /// <param name="toFilename"></param>
+        /// <returns></returns>
         [HttpGet]
         public ActionResult Handle(string path, string[] items, string toFilename)
         {
-            var prefix = CommonHelper.GetSettings("PathRoot").Trim('\\', '/');
-            switch (Request["action"])
+            var prefix = CommonHelper.SystemSettings["PathRoot"].Trim('\\', '/');
+            switch (Request.Query["action"])
             {
                 case "download":
-                    string file = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(path) : prefix + path;
-                    //Server.MapPath(path);
+                    string file = string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (path) : prefix + path;
+                    //_hostingEnvironment.WebRootPath + (path);
                     if (System.IO.File.Exists(file))
                     {
                         return this.ResumePhysicalFile(file, Path.GetFileName(file));
                     }
                     break;
                 case "downloadMultiple":
-                    byte[] buffer = SevenZipCompressor.ZipStream(items.Select(s => string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? Server.MapPath(s) : prefix + s).ToList()).ToArray();
+                    byte[] buffer = _sevenZipCompressor.ZipStream(items.Select(s => string.IsNullOrEmpty(prefix) && !Directory.Exists(prefix) ? _hostingEnvironment.WebRootPath + (s) : prefix + s).ToList()).ToArray();
                     return this.ResumeFile(buffer, Path.GetFileName(toFilename));
             }
             return Content("null");

+ 6 - 5
src/Masuit.MyBlogs.WebApp/Controllers/HealthController.cs → src/Masuit.MyBlogs.Core/Controllers/HealthController.cs

@@ -1,10 +1,11 @@
-using System.Web.Http;
-using System.Web.Http.Results;
+using Microsoft.AspNetCore.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
-    [Route("health/{action}")]
-    public class HealthController : ApiController
+    /// <summary>
+    /// 健康检查
+    /// </summary>
+    public class HealthController : Controller
     {
         /// <summary>
         /// 心跳检测

+ 94 - 64
src/Masuit.MyBlogs.WebApp/Controllers/HomeController.cs → src/Masuit.MyBlogs.Core/Controllers/HomeController.cs

@@ -1,40 +1,73 @@
-using Common;
-using EFSecondLevelCache;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
+using AutoMapper.QueryableExtensions;
+using EFSecondLevelCache.Core;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.Tools;
-using Masuit.Tools.Net;
-using Models.DTO;
-using Models.Entity;
-using Models.Enum;
-using Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Threading.Tasks;
-using System.Web.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 首页
+    /// </summary>
     public class HomeController : BaseController
     {
-        public IPostBll PostBll { get; set; }
-        public ICategoryBll CategoryBll { get; set; }
-        public ICommentBll CommentBll { get; set; }
-        public ISearchDetailsBll SearchDetailsBll { get; set; }
-        public INoticeBll NoticeBll { get; set; }
-        public IPostAccessRecordBll PostAccessRecordBll { get; set; }
-        public IFastShareBll FastShareBll { get; set; }
-        public HomeController(IPostBll postBll, ICommentBll commentBll, ICategoryBll categoryBll, ISearchDetailsBll searchDetailsBll, INoticeBll noticeBll, IPostAccessRecordBll postAccessRecordBll, IFastShareBll fastShareBll)
+        /// <summary>
+        /// 文章
+        /// </summary>
+        public IPostService PostService { get; set; }
+
+        /// <summary>
+        /// 分类
+        /// </summary>
+        public ICategoryService CategoryService { get; set; }
+
+        /// <summary>
+        /// 搜索关键词推荐
+        /// </summary>
+        public ISearchDetailsService SearchDetailsService { get; set; }
+
+        /// <summary>
+        /// 网站公告
+        /// </summary>
+        public INoticeService NoticeService { get; set; }
+
+        /// <summary>
+        /// 文章访问统计
+        /// </summary>
+        public IPostAccessRecordService PostAccessRecordService { get; set; }
+
+        /// <summary>
+        /// 快速分享
+        /// </summary>
+        public IFastShareService FastShareService { get; set; }
+
+        /// <summary>
+        /// 首页
+        /// </summary>
+        /// <param name="postService"></param>
+        /// <param name="categoryService"></param>
+        /// <param name="searchDetailsService"></param>
+        /// <param name="noticeService"></param>
+        /// <param name="postAccessRecordService"></param>
+        /// <param name="fastShareService"></param>
+        public HomeController(IPostService postService, ICategoryService categoryService, ISearchDetailsService searchDetailsService, INoticeService noticeService, IPostAccessRecordService postAccessRecordService, IFastShareService fastShareService)
         {
-            CategoryBll = categoryBll;
-            PostBll = postBll;
-            CommentBll = commentBll;
-            SearchDetailsBll = searchDetailsBll;
-            NoticeBll = noticeBll;
-            PostAccessRecordBll = postAccessRecordBll;
-            FastShareBll = fastShareBll;
+            CategoryService = categoryService;
+            PostService = postService;
+            SearchDetailsService = searchDetailsService;
+            NoticeService = noticeService;
+            PostAccessRecordService = postAccessRecordService;
+            FastShareService = fastShareService;
         }
 
         /// <summary>
@@ -45,15 +78,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         public ActionResult Index(OrderBy orderBy = OrderBy.ModifyDate)
         {
             ViewBag.Total = 0;
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            var tops = PostBll.LoadEntitiesFromL2CacheNoTracking<DateTime, PostOutputDto>(t => t.Status == Status.Pended && t.IsBanner, p => p.ModifyDate, false).Select(p => new
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            var tops = PostService.LoadEntitiesFromL2CacheNoTracking(t => t.Status == Status.Pended && t.IsBanner, p => p.ModifyDate, false).Select(p => new
             {
                 p.Title,
                 p.Description,
                 p.Id,
                 p.ImageUrl
             }).ToList();
-            List<FastShare> fastShares = FastShareBll.GetAllFromL2CacheNoTracking(s => s.Sort).ToList();
+            List<FastShare> fastShares = FastShareService.GetAllFromL2CacheNoTracking(s => s.Sort).ToList();
             ViewBag.FastShare = fastShares;
             var viewModel = GetIndexPageViewModel(1, 15, orderBy, user);
             var banner = new List<PostOutputDto>();
@@ -75,8 +108,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Route("p/{page:int?}/{size:int?}/{orderBy:int?}")]
         public ActionResult Post(int page = 1, int size = 15, OrderBy orderBy = OrderBy.ModifyDate)
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            ViewBag.Total = PostBll.LoadEntitiesFromL2CacheNoTracking<PostOutputDto>(p => p.Status == Status.Pended || user.IsAdmin && !p.IsFixedTop).Count(p => !p.IsFixedTop);
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            ViewBag.Total = PostService.LoadEntitiesFromL2Cache<PostOutputDto>(p => p.Status == Status.Pended || user.IsAdmin && !p.IsFixedTop).Count(p => !p.IsFixedTop);
             var viewModel = GetIndexPageViewModel(page, size, orderBy, user);
             return View(viewModel);
         }
@@ -93,30 +126,30 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         public ActionResult Tag(string id, int page = 1, int size = 15, OrderBy orderBy = OrderBy.ModifyDate)
         {
             IList<PostOutputDto> posts;
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            var temp = PostBll.LoadEntitiesNoTracking<PostOutputDto>(p => p.Label.Contains(id) && (p.Status == Status.Pended || user.IsAdmin)).OrderByDescending(p => p.IsFixedTop);
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            var temp = PostService.LoadEntities<PostOutputDto>(p => p.Label.Contains(id) && (p.Status == Status.Pended || user.IsAdmin)).OrderByDescending(p => p.IsFixedTop);
             switch (orderBy)
             {
                 case OrderBy.CommentCount:
-                    posts = temp.ThenByDescending(p => p.Comment.Count).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = temp.ThenByDescending(p => p.Comment.Count).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.PostDate:
-                    posts = temp.ThenByDescending(p => p.PostDate).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = temp.ThenByDescending(p => p.PostDate).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.ViewCount:
-                    posts = temp.ThenByDescending(p => p.ViewCount).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = temp.ThenByDescending(p => p.ViewCount).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.VoteCount:
-                    posts = temp.ThenByDescending(p => p.VoteUpCount).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = temp.ThenByDescending(p => p.VoteUpCount).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.AverageViewCount:
-                    posts = temp.ThenByDescending(p => p.AverageViewCount).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = temp.ThenByDescending(p => p.AverageViewCount).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 default:
-                    posts = temp.ThenByDescending(p => p.ModifyDate).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = temp.ThenByDescending(p => p.ModifyDate).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
             }
-            var viewModel = GetIndexPageViewModel(0, 0, orderBy, user);
+            var viewModel = GetIndexPageViewModel(1, 1, orderBy, user);
             ViewBag.Total = temp.Count();
             ViewBag.Tag = id;
             viewModel.Posts = posts;
@@ -135,10 +168,10 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Route("cat/{id:int}/{page:int?}/{size:int?}/{orderBy:int?}")]
         public async Task<ActionResult> Category(int id, int page = 1, int size = 15, OrderBy orderBy = OrderBy.ModifyDate)
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            var cat = await CategoryBll.GetByIdAsync(id).ConfigureAwait(true);
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            var cat = await CategoryService.GetByIdAsync(id).ConfigureAwait(true);
             if (cat is null) return RedirectToAction("Index", "Error");
-            var posts = PostBll.LoadEntitiesNoTracking(p => p.CategoryId == cat.Id && (p.Status == Status.Pended || user.IsAdmin)).OrderByDescending(p => p.IsFixedTop);
+            var posts = PostService.LoadEntitiesNoTracking(p => p.CategoryId == cat.Id && (p.Status == Status.Pended || user.IsAdmin)).OrderByDescending(p => p.IsFixedTop);
             ViewBag.Total = posts.Count();
             switch (orderBy)
             {
@@ -161,10 +194,10 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     posts = posts.ThenByDescending(p => p.ModifyDate);
                     break;
             }
-            var viewModel = GetIndexPageViewModel(0, 0, orderBy, user);
+            var viewModel = GetIndexPageViewModel(1, 1, orderBy, user);
             ViewBag.CategoryName = cat.Name;
             ViewBag.Desc = cat.Description;
-            viewModel.Posts = posts.Skip(size * (page - 1)).Take(size).ToList().Mapper<IList<PostOutputDto>>();
+            viewModel.Posts = posts.Skip(size * (page - 1)).Take(size).ProjectTo<PostOutputDto>().Cacheable().ToList();
             return View(viewModel);
         }
 
@@ -178,11 +211,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// <returns></returns>
         private IndexPageViewModel GetIndexPageViewModel(int page, int size, OrderBy orderBy, UserInfoOutputDto user)
         {
-            IQueryable<PostOutputDto> postList = PostBll.LoadEntitiesNoTracking<PostOutputDto>(p => (p.Status == Status.Pended || user.IsAdmin)); //准备文章的查询
-            var notices = NoticeBll.LoadPageEntitiesFromL2CacheNoTracking<DateTime, NoticeOutputDto>(1, 5, out int _, n => (n.Status == Status.Display || user.IsAdmin), n => n.ModifyDate, false).ToList(); //加载前5条公告
-            var cats = CategoryBll.LoadEntitiesFromL2CacheNoTracking<string, CategoryOutputDto>(c => c.Status == Status.Available, c => c.Name); //加载分类目录
+            IQueryable<PostOutputDto> postList = PostService.LoadEntities<PostOutputDto>(p => (p.Status == Status.Pended || user.IsAdmin)); //准备文章的查询
+            var notices = NoticeService.LoadPageEntitiesFromL2Cache<DateTime, NoticeOutputDto>(1, 5, out int _, n => (n.Status == Status.Display || user.IsAdmin), n => n.ModifyDate, false).ToList(); //加载前5条公告
+            var cats = CategoryService.LoadEntitiesFromL2Cache<string, CategoryOutputDto>(c => c.Status == Status.Available, c => c.Name).ToList(); //加载分类目录
             var start = DateTime.Today.AddDays(-7);
-            var hotSearches = SearchDetailsBll.LoadEntitiesNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(10).Select(g => new KeywordsRankOutputDto()
+            var hotSearches = SearchDetailsService.LoadEntitiesNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).GroupBy(s => s.KeyWords).OrderByDescending(g => g.Count()).Take(10).Select(g => new KeywordsRankOutputDto()
             {
                 KeyWords = g.FirstOrDefault().KeyWords,
                 SearchCount = g.Count()
@@ -190,9 +223,6 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             Expression<Func<PostOutputDto, double>> order = p => p.ViewCount;
             switch (new Random().Next() % 3)
             {
-                case 0:
-                    order = p => p.ViewCount;
-                    break;
                 case 1:
                     order = p => p.VoteUpCount;
                     break;
@@ -201,13 +231,13 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     break;
             }
             var hot6Post = postList.OrderByDescending(order).Skip(0).Take(5).Cacheable().ToList(); //热门文章
-            var topPostWeek = PostBll.SqlQuery<SimplePostModel>("SELECT [Id],[Title] from Post WHERE Id in (SELECT top 10 PostId FROM [dbo].[PostAccessRecord] where DATEDIFF(week,AccessTime,getdate())<=1 GROUP BY PostId ORDER BY sum(ClickCount) desc)").ToList(); //文章周排行
-            var topPostMonth = PostBll.SqlQuery<SimplePostModel>("SELECT [Id],[Title] from Post WHERE Id in (SELECT top 10 PostId FROM [dbo].[PostAccessRecord] where DATEDIFF(month,AccessTime,getdate())<=1 GROUP BY PostId ORDER BY sum(ClickCount) desc)").ToList(); //文章月排行
-            var topPostYear = PostBll.SqlQuery<SimplePostModel>("SELECT [Id],[Title] from Post WHERE Id in (SELECT top 10 PostId FROM [dbo].[PostAccessRecord] where DATEDIFF(year,AccessTime,getdate())<=1 GROUP BY PostId ORDER BY sum(ClickCount) desc)").ToList(); //文章年度排行
+            var topPostWeek = PostService.SqlQuery<SimplePostModel>("SELECT [Id],[Title] from Post WHERE Id in (SELECT top 10 PostId FROM [dbo].[PostAccessRecord] where DATEDIFF(week,AccessTime,getdate())<=1 GROUP BY PostId ORDER BY sum(ClickCount) desc)").ToList(); //文章周排行
+            var topPostMonth = PostService.SqlQuery<SimplePostModel>("SELECT [Id],[Title] from Post WHERE Id in (SELECT top 10 PostId FROM [dbo].[PostAccessRecord] where DATEDIFF(month,AccessTime,getdate())<=1 GROUP BY PostId ORDER BY sum(ClickCount) desc)").ToList(); //文章月排行
+            var topPostYear = PostService.SqlQuery<SimplePostModel>("SELECT [Id],[Title] from Post WHERE Id in (SELECT top 10 PostId FROM [dbo].[PostAccessRecord] where DATEDIFF(year,AccessTime,getdate())<=1 GROUP BY PostId ORDER BY sum(ClickCount) desc)").ToList(); //文章年度排行
             var tags = new List<string>(); //标签云
             var tagdic = new Dictionary<string, int>();
             var newdic = new Dictionary<string, int>(); //标签云最终结果
-            postList.Select(p => p.Label).ToList().ForEach(m =>
+            postList.Select(p => p.Label).Cacheable().ToList().ForEach(m =>
             {
                 if (!string.IsNullOrEmpty(m))
                 {
@@ -231,31 +261,31 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             switch (orderBy) //文章排序
             {
                 case OrderBy.CommentCount:
-                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.Comment.Count).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.Comment.Count).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.PostDate:
-                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.PostDate).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.PostDate).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.ViewCount:
-                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.ViewCount).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.ViewCount).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.VoteCount:
-                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.VoteUpCount).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.VoteUpCount).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 case OrderBy.AverageViewCount:
-                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.AverageViewCount).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.AverageViewCount).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
                 default:
-                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.ModifyDate).Skip(size * (page - 1)).Take(size).ToList();
+                    posts = postList.Where(p => !p.IsFixedTop).OrderByDescending(p => p.ModifyDate).Skip(size * (page - 1)).Take(size).Cacheable().ToList();
                     break;
             }
             if (page == 1)
             {
-                posts = postList.Where(p => p.IsFixedTop).OrderByDescending(p => p.ModifyDate).AsEnumerable().Union(posts).ToList();
+                //posts = postList.Where(p => p.IsFixedTop).OrderByDescending(p => p.ModifyDate).AsEnumerable().Union(posts).ToList();
             }
             return new IndexPageViewModel()
             {
-                Categories = cats.ToList(),
+                Categories = cats,
                 HotSearch = hotSearches,
                 Notices = notices,
                 Posts = posts,

+ 102 - 27
src/Masuit.MyBlogs.WebApp/Controllers/LinksController.cs → src/Masuit.MyBlogs.Core/Controllers/LinksController.cs

@@ -1,45 +1,61 @@
 using Common;
-using Masuit.MyBlogs.WebApp.Models;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.Tools;
-using Masuit.Tools.Net;
-using Models.DTO;
-using Models.Entity;
-using Models.Enum;
+using Masuit.Tools.Core.Net;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Net.Http;
 using System.Net.Http.Headers;
 using System.Threading.Tasks;
-using System.Web.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 友情链接管理
+    /// </summary>
     public class LinksController : BaseController
     {
+        /// <summary>
+        /// 友情链接页
+        /// </summary>
+        /// <returns></returns>
         [Route("links")]
         public ActionResult Index()
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
-            List<LinksOutputDto> list = LinksBll.LoadEntitiesNoTracking<object, LinksOutputDto>(l => l.Status == Status.Available, l => new { l.Recommend, l.Id }, false).ToList();
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            List<LinksOutputDto> list = LinksService.LoadEntities<object, LinksOutputDto>(l => l.Status == Status.Available, l => l.Recommend, false).ToList();
             if (user != null && user.IsAdmin)
             {
                 return View("Index_Admin", list);
             }
+
             return View(list);
         }
 
+        /// <summary>
+        /// 申请友链
+        /// </summary>
+        /// <param name="links"></param>
+        /// <returns></returns>
         public async Task<ActionResult> Apply(Links links)
         {
             if (!links.Url.MatchUrl())
             {
                 return ResultData(null, false, "添加失败!链接非法!");
             }
+
             var host = new Uri(links.Url).Host;
-            if (LinksBll.Any(l => l.Url.Contains(host)))
+            if (LinksService.Any(l => l.Url.Contains(host)))
             {
                 return ResultData(null, false, "添加失败!检测到您的网站已经是本站的友情链接了!");
             }
+
             Uri uri = new Uri(links.Url);
             using (HttpClient client = new HttpClient()
             {
@@ -48,36 +64,77 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             })
             {
                 client.DefaultRequestHeaders.UserAgent.Add(ProductInfoHeaderValue.Parse("Mozilla/5.0"));
-                client.DefaultRequestHeaders.Referrer = Request.Url;
+                client.DefaultRequestHeaders.Referrer = new Uri(Request.Host.Host);
                 return await await client.GetAsync(uri.PathAndQuery).ContinueWith(async t =>
                 {
                     if (t.IsFaulted || t.IsCanceled)
                     {
                         return ResultData(null, false, "添加失败!检测到您的网站疑似挂了,或者连接到你网站的时候超时,请检查下!");
                     }
+
                     var res = await t;
                     if (res.IsSuccessStatusCode)
                     {
                         var s = await res.Content.ReadAsStringAsync();
-                        if (s.Contains(CommonHelper.GetSettings("Domain")))
+                        if (s.Contains(CommonHelper.SystemSettings["Domain"]))
                         {
-                            bool b = LinksBll.AddOrUpdateSaved(l => l.Url, links) > 0;
+                            var entry = LinksService.GetFirstEntity(l => l.Url.Equals(links.Url));
+                            bool b;
+                            if (entry is null)
+                            {
+                                b = LinksService.AddEntitySaved(links) != null;
+                            }
+                            else
+                            {
+                                entry.Url = links.Url;
+                                entry.Except = links.Except;
+                                entry.Name = links.Name;
+                                entry.Recommend = links.Recommend;
+                                b = LinksService.UpdateEntitySaved(entry);
+                            }
+
                             return ResultData(null, b, b ? "添加成功!这可能有一定的延迟,如果没有看到您的链接,请稍等几分钟后刷新页面即可,如有疑问,请联系站长。" : "添加失败!这可能是由于网站服务器内部发生了错误,如有疑问,请联系站长。");
                         }
-                        return ResultData(null, false, $"添加失败!检测到您的网站上未将本站设置成友情链接,请先将本站主域名:{CommonHelper.GetSettings("Domain")}在您的网站设置为友情链接,并且能够展示后,再次尝试添加即可!");
+
+                        return ResultData(null, false, $"添加失败!检测到您的网站上未将本站设置成友情链接,请先将本站主域名:{CommonHelper.SystemSettings["Domain"]}在您的网站设置为友情链接,并且能够展示后,再次尝试添加即可!");
                     }
+
                     return ResultData(null, false, "添加失败!检测到您的网站疑似挂了!返回状态码为:" + res.StatusCode);
                 });
             }
         }
 
+        /// <summary>
+        /// 添加友链
+        /// </summary>
+        /// <param name="links"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Add(Links links)
         {
-            bool b = LinksBll.AddOrUpdateSaved(l => l.Url, links) > 0;
+            var entry = LinksService.GetById(links.Id);
+            bool b;
+            if (entry is null)
+            {
+                b = LinksService.AddEntitySaved(links) != null;
+            }
+            else
+            {
+                entry.Url = links.Url;
+                entry.Except = links.Except;
+                entry.Name = links.Name;
+                entry.Recommend = links.Recommend;
+                b = LinksService.UpdateEntitySaved(entry);
+            }
+
             return b ? ResultData(null, message: "添加成功!") : ResultData(null, false, "添加失败!");
         }
 
+        /// <summary>
+        /// 检测回链
+        /// </summary>
+        /// <param name="link"></param>
+        /// <returns></returns>
         [Authority]
         public async Task<ActionResult> Check(string link)
         {
@@ -100,39 +157,57 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     if (res.IsSuccessStatusCode)
                     {
                         var s = await res.Content.ReadAsStringAsync();
-                        if (s.Contains(CommonHelper.GetSettings("Domain")))
+                        if (s.Contains(CommonHelper.SystemSettings["Domain"]))
                         {
                             return ResultData(null, true, "友情链接正常!");
                         }
+
                         return ResultData(null, false, link + " 对方似乎没有本站的友情链接!");
                     }
+
                     return ResultData(null, false, link + " 对方网站返回错误的状态码!http响应码为:" + res.StatusCode);
                 });
             }
         }
 
+        /// <summary>
+        /// 删除友链
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Delete(int id)
         {
-            bool b = LinksBll.DeleteByIdSaved(id);
+            bool b = LinksService.DeleteByIdSaved(id);
             return ResultData(null, b, b ? "删除成功!" : "删除失败!");
         }
 
+        /// <summary>
+        /// 编辑友链
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Edit(Links model)
         {
-            Links links = LinksBll.GetById(model.Id);
+            Links links = LinksService.GetById(model.Id);
             links.Name = model.Name;
             links.Url = model.Url;
-            bool b = LinksBll.UpdateEntitySaved(links);
+            bool b = LinksService.UpdateEntitySaved(links);
             return ResultData(null, b, b ? "保存成功" : "保存失败");
         }
 
+        /// <summary>
+        /// 分页数据
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult GetPageData(int page = 1, int size = 10)
         {
-            List<Links> list = LinksBll.GetAll().OrderBy(p => p.Status).ThenByDescending(l => new { l.Recommend, l.Id }).Skip((page - 1) * size).Take(size).ToList();
-            var total = LinksBll.GetAll().Count();
+            List<Links> list = LinksService.GetAll().OrderBy(p => p.Status).ThenByDescending(p => p.Recommend).ThenByDescending(p => p.Id).Skip((page - 1) * size).Take(size).ToList();
+            var total = LinksService.GetAll().Count();
             var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
             return PageResult(list, pageCount, total);
         }
@@ -146,9 +221,9 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [HttpPost]
         public ActionResult ToggleWhitelist(int id, bool state)
         {
-            Links link = LinksBll.GetById(id);
+            Links link = LinksService.GetById(id);
             link.Except = !state;
-            bool b = LinksBll.UpdateEntitySaved(link);
+            bool b = LinksService.UpdateEntitySaved(link);
             return ResultData(null, b, b ? "切换成功!" : "切换失败!");
         }
 
@@ -161,9 +236,9 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [HttpPost]
         public ActionResult ToggleRecommend(int id, bool state)
         {
-            Links link = LinksBll.GetById(id);
+            Links link = LinksService.GetById(id);
             link.Recommend = !state;
-            bool b = LinksBll.UpdateEntitySaved(link);
+            bool b = LinksService.UpdateEntitySaved(link);
             return ResultData(null, b, b ? "切换成功!" : "切换失败!");
         }
 
@@ -176,9 +251,9 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [HttpPost]
         public ActionResult Toggle(int id, bool state)
         {
-            Links link = LinksBll.GetById(id);
+            Links link = LinksService.GetById(id);
             link.Status = !state ? Status.Available : Status.Unavailable;
-            bool b = LinksBll.UpdateEntitySaved(link);
+            bool b = LinksService.UpdateEntitySaved(link);
             return ResultData(null, b, b ? "切换成功!" : "切换失败!");
         }
     }

+ 102 - 0
src/Masuit.MyBlogs.Core/Controllers/MenuController.cs

@@ -0,0 +1,102 @@
+using AutoMapper;
+using Common;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.Tools.Systems;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 菜单管理
+    /// </summary>
+    public class MenuController : AdminController
+    {
+        /// <summary>
+        /// 菜单数据服务
+        /// </summary>
+        public IMenuService MenuService { get; set; }
+
+        /// <summary>
+        /// 菜单管理
+        /// </summary>
+        /// <param name="menuService"></param>
+        public MenuController(IMenuService menuService)
+        {
+            MenuService = menuService;
+        }
+
+        /// <summary>
+        /// 获取菜单
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetMenus()
+        {
+            var menus = MenuService.GetAll(m => m.Sort).ToList();
+            return ResultData(menus);
+        }
+
+        /// <summary>
+        /// 获取菜单类型
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetMenuType()
+        {
+            Array array = Enum.GetValues(typeof(MenuType));
+            var list = new List<object>();
+            foreach (Enum e in array)
+            {
+                list.Add(new
+                {
+                    e,
+                    name = e.GetDisplay()
+                });
+            }
+            return ResultData(list);
+        }
+
+        /// <summary>
+        /// 删除菜单
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public ActionResult Delete(int id)
+        {
+            var menus = MenuService.GetChildrenMenusByParentId(id);
+            bool b = MenuService.DeleteEntitiesSaved(menus);
+            return ResultData(null, b, b ? "删除成功" : "删除失败");
+        }
+
+
+        /// <summary>
+        /// 保持菜单
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        public ActionResult Save(MenuInputDto model)
+        {
+            if (string.IsNullOrEmpty(model.Icon) || !model.Icon.Contains("/"))
+            {
+                model.Icon = null;
+            }
+            Menu m = MenuService.GetById(model.Id);
+            if (m == null)
+            {
+                var menu = MenuService.AddEntitySaved(model.Mapper<Menu>());
+                if (menu != null)
+                {
+                    return ResultData(menu, true, "添加成功");
+                }
+                return ResultData(null, false, "添加失败");
+            }
+            Mapper.Map(model, m);
+            bool b = MenuService.UpdateEntitySaved(m);
+            return ResultData(null, b, b ? "修改成功" : "修改失败");
+        }
+    }
+}

+ 95 - 25
src/Masuit.MyBlogs.WebApp/Controllers/MiscController.cs → src/Masuit.MyBlogs.Core/Controllers/MiscController.cs

@@ -1,34 +1,60 @@
 using Common;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.Tools;
+using Masuit.Tools.Core.Net;
 using Masuit.Tools.Html;
-using Masuit.Tools.Net;
-using Models.DTO;
-using Models.Entity;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.IO;
 using System.Linq;
 using System.Text.RegularExpressions;
-using System.Web.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 杂项页
+    /// </summary>
     public class MiscController : BaseController
     {
-        public IMiscBll MiscBll { get; set; }
-        public IDonateBll DonateBll { get; set; }
+        /// <summary>
+        /// MiscService
+        /// </summary>
+        public IMiscService MiscService { get; set; }
 
-        public MiscController(IMiscBll miscBll, IDonateBll donateBll)
+        /// <summary>
+        /// 捐赠
+        /// </summary>
+        public IDonateService DonateService { get; set; }
+
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// 杂项页
+        /// </summary>
+        /// <param name="miscService"></param>
+        /// <param name="donateService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public MiscController(IMiscService miscService, IDonateService donateService, IHostingEnvironment hostingEnvironment)
         {
-            MiscBll = miscBll;
-            DonateBll = donateBll;
+            MiscService = miscService;
+            DonateService = donateService;
+            _hostingEnvironment = hostingEnvironment;
         }
 
+        /// <summary>
+        /// 杂项页
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Route("misc/{id:int}")]
         public ActionResult Index(int id)
         {
-            Misc misc = MiscBll.GetById(id);
+            Misc misc = MiscService.GetById(id);
             if (misc is null)
             {
                 return RedirectToAction("Index", "Error");
@@ -36,10 +62,14 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return View(misc);
         }
 
+        /// <summary>
+        /// 捐赠
+        /// </summary>
+        /// <returns></returns>
         [Route("donate")]
         public ActionResult Donate()
         {
-            var user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            var user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
             if (user != null && user.IsAdmin)
             {
                 return View("Donate_Admin");
@@ -47,10 +77,16 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return View();
         }
 
+        /// <summary>
+        /// 捐赠列表
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
         [Route("donatelist")]
         public ActionResult DonateList(int page = 1, int size = 10)
         {
-            var list = DonateBll.LoadPageEntitiesFromL2CacheNoTracking(page, size, out int total, d => true, d => d.DonateTime, false).Select(d => new
+            var list = DonateService.LoadPageEntitiesFromL2CacheNoTracking(page, size, out int total, d => true, d => d.DonateTime, false).Select(d => new
             {
                 d.NickName,
                 d.EmailDisplay,
@@ -63,23 +99,36 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return PageResult(list, pageCount, total);
         }
 
+        /// <summary>
+        /// 关于
+        /// </summary>
+        /// <returns></returns>
         [Route("about")]
         public ActionResult About()
         {
             return View();
         }
 
+        /// <summary>
+        /// 声明
+        /// </summary>
+        /// <returns></returns>
         [Route("disclaimer")]
         public ActionResult Disclaimer()
         {
             return View();
         }
 
-        [ValidateInput(false), Authority]
+        /// <summary>
+        /// 创建页面
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        [Authority]
         public ActionResult Write(Misc model)
         {
             model.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(model.Content?.Trim(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
-            var e = MiscBll.AddEntitySaved(model);
+            var e = MiscService.AddEntitySaved(model);
             if (e != null)
             {
                 return ResultData(null, message: "发布成功");
@@ -87,10 +136,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null, false, "发布失败");
         }
 
+        /// <summary>
+        /// 删除页面
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Delete(int id)
         {
-            var post = MiscBll.GetById(id);
+            var post = MiscService.GetById(id);
             if (post is null)
             {
                 return ResultData(null, false, "杂项页已经被删除!");
@@ -103,32 +157,43 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 {
                     try
                     {
-                        System.IO.File.Delete(Path.Combine(Server.MapPath("/"), path));
+                        System.IO.File.Delete(Path.Combine(_hostingEnvironment.WebRootPath + path));
                     }
                     catch (IOException)
                     {
                     }
                 }
             }
-            bool b = MiscBll.DeleteByIdSaved(id);
+            bool b = MiscService.DeleteByIdSaved(id);
             return ResultData(null, b, b ? "删除成功" : "删除失败");
         }
 
-        [ValidateInput(false), Authority]
+        /// <summary>
+        /// 编辑页面
+        /// </summary>
+        /// <param name="misc"></param>
+        /// <returns></returns>
+        [Authority]
         public ActionResult Edit(Misc misc)
         {
-            var entity = MiscBll.GetById(misc.Id);
+            var entity = MiscService.GetById(misc.Id);
             entity.ModifyDate = DateTime.Now;
             entity.Title = misc.Title;
             entity.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(misc.Content, @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
-            bool b = MiscBll.UpdateEntitySaved(entity);
+            bool b = MiscService.UpdateEntitySaved(entity);
             return ResultData(null, b, b ? "修改成功" : "修改失败");
         }
 
+        /// <summary>
+        /// 分页数据
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult GetPageData(int page = 1, int size = 10)
         {
-            var list = MiscBll.LoadPageEntitiesNoTracking(page, size, out int total, n => true, n => n.ModifyDate, false).Select(m => new
+            var list = MiscService.LoadPageEntitiesNoTracking(page, size, out int total, n => true, n => n.ModifyDate, false).Select(m => new
             {
                 m.Id,
                 m.Title,
@@ -139,10 +204,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return PageResult(list, pageCount, total);
         }
 
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Get(int id)
         {
-            var notice = MiscBll.GetById(id);
+            var notice = MiscService.GetById(id);
             return ResultData(notice.MapTo<MiscOutputDto>());
         }
     }

+ 349 - 0
src/Masuit.MyBlogs.Core/Controllers/MsgController.cs

@@ -0,0 +1,349 @@
+using Common;
+using Hangfire;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Html;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Net.Http.Headers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 留言板和站内信
+    /// </summary>
+    public class MsgController : BaseController
+    {
+        /// <summary>
+        /// 留言
+        /// </summary>
+        public ILeaveMessageService LeaveMessageService { get; set; }
+
+        /// <summary>
+        /// 站内信
+        /// </summary>
+        public IInternalMessageService MessageService { get; set; }
+
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// 留言板和站内信
+        /// </summary>
+        /// <param name="leaveMessageService"></param>
+        /// <param name="messageService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public MsgController(ILeaveMessageService leaveMessageService, IInternalMessageService messageService, IHostingEnvironment hostingEnvironment)
+        {
+            LeaveMessageService = leaveMessageService;
+            MessageService = messageService;
+            _hostingEnvironment = hostingEnvironment;
+        }
+
+        /// <summary>
+        /// 留言板
+        /// </summary>
+        /// <returns></returns>
+        [ResponseCache(Duration = 10, VaryByQueryKeys = new[]
+        {
+            "cid"
+        }), Route("msg")]
+        public ActionResult Index()
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            ViewBag.TotalCount = LeaveMessageService.LoadEntitiesNoTracking(m => m.ParentId == 0 && m.Status == Status.Pended).Count();
+            if (user.IsAdmin)
+            {
+                return View("Index_Admin");
+            }
+            return View();
+        }
+
+        /// <summary>
+        /// 获取留言
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="cid"></param>
+        /// <returns></returns>
+        public ActionResult GetMsgs(int page = 1, int size = 10, int cid = 0)
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            int total;
+            if (cid != 0)
+            {
+                int pid = LeaveMessageService.GetParentMessageIdByChildId(cid);
+                var single = LeaveMessageService.GetSelfAndAllChildrenMessagesByParentId(pid).ToList();
+                if (single.Any())
+                {
+                    total = 1;
+                    return ResultData(new
+                    {
+                        total,
+                        parentTotal = total,
+                        page,
+                        size,
+                        rows = single.Mapper<IList<LeaveMessageViewModel>>()
+                    });
+                }
+            }
+            IEnumerable<LeaveMessage> parent = LeaveMessageService.LoadPageEntitiesNoTracking(page, size, out total, m => m.ParentId == 0 && (m.Status == Status.Pended || user.IsAdmin), m => m.PostDate, false);
+            if (!parent.Any())
+            {
+                return ResultData(null, false, "没有留言");
+            }
+            var list = new List<LeaveMessageViewModel>();
+            parent.ForEach(c => LeaveMessageService.GetSelfAndAllChildrenMessagesByParentId(c.Id).ForEach(result => list.Add(result.Mapper<LeaveMessageViewModel>())));
+            var qlist = list.Where(c => c.Status == Status.Pended || user.IsAdmin);
+            if (total > 0)
+            {
+                return ResultData(new
+                {
+                    total,
+                    parentTotal = total,
+                    page,
+                    size,
+                    rows = qlist
+                });
+            }
+            return ResultData(null, false, "没有留言");
+        }
+
+        /// <summary>
+        /// 发表留言
+        /// </summary>
+        /// <param name="msg"></param>
+        /// <returns></returns>
+        [HttpPost, ValidateAntiForgeryToken]
+        public ActionResult Put(LeaveMessageInputDto msg)
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            msg.Content = msg.Content.Trim().Replace("<p><br></p>", string.Empty);
+            if (msg.Content.RemoveHtml().Trim().Equals(HttpContext.Session.GetByRedis<string>("msg")))
+            {
+                return ResultData(null, false, "您刚才已经发表过一次留言了!");
+            }
+            if (Regex.Match(msg.Content, CommonHelper.ModRegex).Length <= 0)
+            {
+                msg.Status = Status.Pended;
+            }
+
+            if (user != null)
+            {
+                msg.NickName = user.NickName;
+                msg.QQorWechat = user.QQorWechat;
+                msg.Email = user.Email;
+                if (user.IsAdmin)
+                {
+                    msg.Status = Status.Pended;
+                    msg.IsMaster = true;
+                }
+            }
+            msg.PostDate = DateTime.Now;
+            msg.Content = Regex.Replace(msg.Content.HtmlSantinizerStandard().ConvertImgSrcToRelativePath(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>");
+            msg.Browser = msg.Browser ?? Request.Headers[HeaderNames.UserAgent];
+            msg.IP = HttpContext.Connection.RemoteIpAddress.ToString();
+            LeaveMessage msg2 = LeaveMessageService.AddEntitySaved(msg.Mapper<LeaveMessage>());
+            if (msg2 != null)
+            {
+                HttpContext.Session.SetByRedis("msg", msg.Content.RemoveHtml().Trim());
+                var email = CommonHelper.SystemSettings["ReceiveEmail"];
+                string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/notify.html").Replace("{{title}}", "网站留言板").Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{nickname}}", msg2.NickName).Replace("{{content}}", msg2.Content);
+                if (msg.Status == Status.Pended)
+                {
+                    if (!msg2.IsMaster)
+                    {
+                        MessageService.AddEntitySaved(new InternalMessage()
+                        {
+                            Title = $"来自【{msg2.NickName}】的新留言",
+                            Content = msg2.Content,
+                            Link = Url.Action("Index", "Msg", new
+                            {
+                                cid = msg2.Id
+                            }, Request.Scheme)
+                        });
+                    }
+#if !DEBUG
+                    if (msg.ParentId == 0)
+                    {
+                        //新评论,只通知博主
+                        BackgroundJob.Enqueue(() => CommonHelper.SendMail(Request.Host + "|博客新留言:", content.Replace("{{link}}", Url.Action("Index", "Msg", new { cid = msg2.Id }, Request.Scheme)), email));
+                    }
+                    else
+                    {
+                        //通知博主和上层所有关联的评论访客
+                        var pid = LeaveMessageService.GetParentMessageIdByChildId(msg2.Id);
+                        var emails = LeaveMessageService.GetSelfAndAllChildrenMessagesByParentId(pid).Select(c => c.Email).ToList();
+                        emails.Add(email);
+                        string link = Url.Action("Index", "Msg", new { cid = msg2.Id }, Request.Scheme);
+                        foreach (var s in emails.Distinct().Except(new[] { msg2.Email }))
+                        {
+                            BackgroundJob.Enqueue(() => CommonHelper.SendMail($"{Request.Host}{CommonHelper.SystemSettings["Title"]} 留言回复:", content.Replace("{{link}}", link), s));
+                        }
+                    }
+#endif
+                    return ResultData(null, true, "留言发表成功,服务器正在后台处理中,这会有一定的延迟,稍后将会显示到列表中!");
+                }
+                BackgroundJob.Enqueue(() => CommonHelper.SendMail(Request.Host + "|博客新留言(待审核):", content.Replace("{{link}}", Url.Action("Index", "Msg", new
+                {
+                    cid = msg2.Id
+                }, Request.Scheme)) + "<p style='color:red;'>(待审核)</p>", email));
+                return ResultData(null, true, "留言发表成功,待站长审核通过以后将显示到列表中!");
+            }
+            return ResultData(null, false, "留言发表失败!");
+        }
+
+        /// <summary>
+        /// 审核
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Pass(int id)
+        {
+            var msg = LeaveMessageService.GetById(id);
+            msg.Status = Status.Pended;
+            bool b = LeaveMessageService.UpdateEntitySaved(msg);
+#if !DEBUG
+            var pid = msg.ParentId == 0 ? msg.Id : LeaveMessageService.GetParentMessageIdByChildId(id);
+            string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + ("template/notify.html")).Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{nickname}}", msg.NickName).Replace("{{content}}", msg.Content);
+            var emails = LeaveMessageService.GetSelfAndAllChildrenMessagesByParentId(pid).Select(c => c.Email).Distinct().Except(new List<string>() { msg.Email }).ToList();
+            string link = Url.Action("Index", "Msg", new { cid = pid }, Request.Scheme);
+            foreach (var s in emails)
+            {
+                BackgroundJob.Enqueue(() => CommonHelper.SendMail($"{Request.Host}{CommonHelper.SystemSettings["Title"]} 留言回复:", content.Replace("{{link}}", link), string.Join(",", s)));
+            }
+#endif
+            return ResultData(null, b, b ? "审核通过!" : "审核失败!");
+        }
+
+        /// <summary>
+        /// 删除留言
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Delete(int id)
+        {
+            var b = LeaveMessageService.DeleteEntitiesSaved(LeaveMessageService.GetSelfAndAllChildrenMessagesByParentId(id).ToList());
+            return ResultData(null, b, b ? "删除成功!" : "删除失败!");
+        }
+
+        /// <summary>
+        /// 获取待审核的留言
+        /// </summary>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult GetPendingMsgs(int page = 1, int size = 10)
+        {
+            List<LeaveMessageOutputDto> list = LeaveMessageService.LoadPageEntities<DateTime, LeaveMessageOutputDto>(page, size, out int total, m => m.Status == Status.Pending, l => l.PostDate, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+
+        #region 站内消息
+
+        /// <summary>
+        /// 已读站内信
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Read(int id)
+        {
+            InternalMessage msg = MessageService.GetById(id);
+            msg.Read = true;
+            MessageService.UpdateEntitySaved(msg);
+            return Content("ok");
+        }
+
+        /// <summary>
+        /// 标记为未读
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Unread(int id)
+        {
+            InternalMessage msg = MessageService.GetById(id);
+            msg.Read = false;
+            MessageService.UpdateEntitySaved(msg);
+            return Content("ok");
+        }
+
+        /// <summary>
+        /// 删除站内信
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult DeleteMsg(int id)
+        {
+            bool b = MessageService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "站内消息删除成功!" : "站内消息删除失败!");
+        }
+
+        /// <summary>
+        /// 获取站内信
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult GetInternalMsgs(int page = 1, int size = 10)
+        {
+            IEnumerable<InternalMessage> msgs = MessageService.LoadPageEntitiesNoTracking(page, size, out int total, m => true, m => m.Time, false);
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(msgs, pageCount, total);
+        }
+
+        /// <summary>
+        /// 获取未读消息
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetUnreadMsgs()
+        {
+            IEnumerable<InternalMessage> msgs = MessageService.LoadEntitiesNoTracking(m => !m.Read, m => m.Time, false);
+            return ResultData(msgs);
+        }
+
+        /// <summary>
+        /// 清除站内信
+        /// </summary>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult ClearMsgs()
+        {
+            MessageService.DeleteEntitySaved(m => m.Read);
+            return ResultData(null, true, "站内消息清除成功!");
+        }
+
+        /// <summary>
+        /// 标记为已读
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult MarkRead(int id)
+        {
+            List<InternalMessage> msgs = MessageService.LoadEntities(m => m.Id <= id).ToList();
+            foreach (var t in msgs)
+            {
+                t.Read = true;
+            }
+            MessageService.UpdateEntities(msgs);
+            MessageService.SaveChanges();
+            return ResultData(null);
+        }
+
+        #endregion
+    }
+}

+ 207 - 0
src/Masuit.MyBlogs.Core/Controllers/NoticeController.cs

@@ -0,0 +1,207 @@
+using Common;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Html;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 网站公告
+    /// </summary>
+    public class NoticeController : BaseController
+    {
+        /// <summary>
+        /// 公告
+        /// </summary>
+        public INoticeService NoticeService { get; set; }
+
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// 网站公告
+        /// </summary>
+        /// <param name="noticeService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public NoticeController(INoticeService noticeService, IHostingEnvironment hostingEnvironment)
+        {
+            NoticeService = noticeService;
+            _hostingEnvironment = hostingEnvironment;
+        }
+
+        /// <summary>
+        /// 公告列表
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Route("notice")]
+        public ActionResult Index(int page = 1, int size = 10, int id = 0)
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            List<NoticeOutputDto> list;
+            int total;
+            if (user != null && user.IsAdmin)
+            {
+                if (id != 0)
+                {
+                    Notice notice = NoticeService.GetById(id);
+                    ViewBag.Total = 1;
+                    return View("Index_Admin", new List<NoticeOutputDto>
+                    {
+                        notice.MapTo<NoticeOutputDto>()
+                    });
+                }
+                list = NoticeService.LoadPageEntities<DateTime, NoticeOutputDto>(page, size, out total, n => n.Status == Status.Display, n => n.ModifyDate, false).ToList();
+                ViewBag.Total = total;
+                return View("Index_Admin", list);
+            }
+            list = NoticeService.LoadPageEntities<DateTime, NoticeOutputDto>(page, size, out total, n => n.Status == Status.Display, n => n.ModifyDate, false).ToList();
+            ViewBag.Total = total;
+            return View(list);
+        }
+
+        /// <summary>
+        /// 公告详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Route("n/{id:int}")]
+        public ActionResult Details(int id)
+        {
+            Notice notice = NoticeService.GetById(id);
+            if (notice != null)
+            {
+                return View(notice);
+            }
+            return RedirectToAction("Index");
+        }
+
+        /// <summary>
+        /// 发布公告
+        /// </summary>
+        /// <param name="notice"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Write(Notice notice)
+        {
+            notice.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(notice.Content, @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
+            Notice e = NoticeService.AddEntitySaved(notice);
+            if (e != null)
+            {
+                return ResultData(null, message: "发布成功");
+            }
+            return ResultData(null, false, "发布失败");
+        }
+
+        /// <summary>
+        /// 删除公告
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Delete(int id)
+        {
+            var post = NoticeService.GetById(id);
+            if (post is null)
+            {
+                return ResultData(null, false, "公告已经被删除!");
+            }
+
+            var srcs = post.Content.MatchImgSrcs();
+            foreach (var path in srcs)
+            {
+                if (path.StartsWith("/"))
+                {
+                    try
+                    {
+                        System.IO.File.Delete(_hostingEnvironment.WebRootPath + path);
+                    }
+                    catch
+                    {
+                    }
+                }
+            }
+            bool b = NoticeService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除成功" : "删除失败");
+        }
+
+        /// <summary>
+        /// 编辑公告
+        /// </summary>
+        /// <param name="notice"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Edit(Notice notice)
+        {
+            Notice entity = NoticeService.GetById(notice.Id);
+            entity.ModifyDate = DateTime.Now;
+            entity.Title = notice.Title;
+            entity.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(notice.Content, @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
+            bool b = NoticeService.UpdateEntitySaved(entity);
+            return ResultData(null, b, b ? "修改成功" : "修改失败");
+        }
+
+        /// <summary>
+        /// 公告分页数据
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        public ActionResult GetPageData(int page = 1, int size = 10)
+        {
+            List<Notice> list = NoticeService.LoadPageEntitiesNoTracking(page, size, out int total, n => true, n => n.ModifyDate, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+
+        /// <summary>
+        /// 公告详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public ActionResult Get(int id)
+        {
+            Notice notice = NoticeService.GetById(id);
+            if (HttpContext.Session.Get<object>("notice" + id) is null)
+            {
+                notice.ViewCount++;
+                NoticeService.UpdateEntitySaved(notice);
+                HttpContext.Session.Set("notice" + id, id);
+            }
+            return ResultData(notice.MapTo<NoticeOutputDto>());
+        }
+
+        /// <summary>
+        /// 最近一条公告
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult Last()
+        {
+            var notice = NoticeService.GetFirstEntityFromL2Cache(n => n.Status == Status.Display, n => n.ModifyDate, false);
+            if (notice != null)
+            {
+                if (HttpContext.Session.Get<object>("notice" + notice.Id) is null)
+                {
+                    notice.ViewCount++;
+                    NoticeService.UpdateEntitySaved(notice);
+                    HttpContext.Session.Set("notice" + notice.Id, notice.Id);
+                }
+                return ResultData(notice.Mapper<NoticeOutputDto>());
+            }
+            return ResultData(null, false);
+        }
+    }
+}

+ 204 - 0
src/Masuit.MyBlogs.Core/Controllers/PassportController.cs

@@ -0,0 +1,204 @@
+using Common;
+using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Configs;
+using Masuit.MyBlogs.Core.Extensions.Hangfire;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools;
+using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Security;
+using Masuit.Tools.Strings;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Web;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 登录授权
+    /// </summary>
+    [ApiExplorerSettings(IgnoreApi = true)]
+    public class PassportController : Controller
+    {
+        /// <summary>
+        /// 用户
+        /// </summary>
+        public IUserInfoService UserInfoService { get; set; }
+        /// <summary>
+        /// 登录记录
+        /// </summary>
+        public ILoginRecordService LoginRecordService { get; set; }
+
+        /// <summary>
+        /// 登录授权
+        /// </summary>
+        /// <param name="userInfoService"></param>
+        /// <param name="loginRecordService"></param>
+        public PassportController(IUserInfoService userInfoService, ILoginRecordService loginRecordService)
+        {
+            UserInfoService = userInfoService;
+            LoginRecordService = loginRecordService;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="data"></param>
+        /// <param name="isTrue"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
+        public ActionResult ResultData(object data, bool isTrue = true, string message = "")
+        {
+            return Json(new
+            {
+                Success = isTrue,
+                Message = message,
+                Data = data
+            });
+        }
+
+        /// <summary>
+        /// 登录页
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult Login()
+        {
+            string from = Request.Query["from"];
+            if (!string.IsNullOrEmpty(from))
+            {
+                from = HttpUtility.UrlDecode(from);
+                Response.Cookies.Append("refer", from);
+            }
+            if (HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) != null)
+            {
+                if (string.IsNullOrEmpty(from))
+                {
+                    return RedirectToAction("Index", "Home");
+                }
+                return Redirect(from);
+            }
+            if (Request.Cookies.Count > 2)
+            {
+                string name = Request.Cookies["username"];
+                string pwd = Request.Cookies["password"]?.DesDecrypt(AppConfig.BaiduAK);
+                var userInfo = UserInfoService.Login(name, pwd);
+                if (userInfo != null)
+                {
+                    Response.Cookies.Append("username", name, new CookieOptions() { Expires = DateTime.Now.AddDays(7) });
+                    Response.Cookies.Append("password", pwd, new CookieOptions() { Expires = DateTime.Now.AddDays(7) });
+                    HttpContext.Session.SetByRedis(SessionKey.UserInfo, userInfo);
+                    HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.LoginRecord), "default", userInfo, HttpContext.Connection.RemoteIpAddress.ToString(), LoginType.Default);
+                    if (string.IsNullOrEmpty(from))
+                    {
+                        return RedirectToAction("Index", "Home");
+                    }
+                    return Redirect(from);
+                }
+            }
+            return View();
+        }
+
+        /// <summary>
+        /// 登陆检查
+        /// </summary>
+        /// <param name="username"></param>
+        /// <param name="password"></param>
+        /// <param name="valid"></param>
+        /// <param name="remem"></param>
+        /// <returns></returns>
+        [HttpPost, ValidateAntiForgeryToken]
+        public ActionResult Login(string username, string password, string valid, string remem)
+        {
+            string validSession = HttpContext.Session.GetByRedis<string>("valid") ?? String.Empty; //将验证码从Session中取出来,用于登录验证比较
+            if (String.IsNullOrEmpty(validSession) || !valid.Trim().Equals(validSession, StringComparison.InvariantCultureIgnoreCase))
+            {
+                return ResultData(null, false, "验证码错误");
+            }
+            HttpContext.Session.RemoveByRedis("valid"); //验证成功就销毁验证码Session,非常重要
+            if (String.IsNullOrEmpty(username.Trim()) || String.IsNullOrEmpty(password.Trim()))
+            {
+                return ResultData(null, false, "用户名或密码不能为空");
+            }
+            var userInfo = UserInfoService.Login(username, password);
+            if (userInfo != null)
+            {
+                HttpContext.Session.SetByRedis(SessionKey.UserInfo, userInfo);
+                if (remem.Trim().Contains(new[] { "on", "true" })) //是否记住登录
+                {
+                    Response.Cookies.Append("username", HttpUtility.UrlEncode(username.Trim()));
+                    Response.Cookies.Append("password", password.Trim().DesEncrypt(AppConfig.BaiduAK), new CookieOptions() { Expires = DateTime.Now.AddDays(7) });
+                }
+                HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.LoginRecord), "default", userInfo, HttpContext.Connection.RemoteIpAddress.ToString(), LoginType.Default);
+                string refer = Request.Cookies["refer"];
+                if (string.IsNullOrEmpty(refer))
+                {
+                    return ResultData(null, true, "/");
+                }
+                return ResultData(null, true, refer);
+            }
+            return ResultData(null, false, "用户名或密码错误");
+        }
+
+        /// <summary>
+        /// 生成验证码
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult ValidateCode()
+        {
+            string code = Tools.Strings.ValidateCode.CreateValidateCode(6);
+            HttpContext.Session.SetByRedis("valid", code); //将验证码生成到Session中
+            var buffer = HttpContext.CreateValidateGraphic(code);
+            return this.ResumeFile(buffer, "image/jpeg");
+        }
+
+        /// <summary>
+        /// 检查验证码
+        /// </summary>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult CheckValidateCode(string code)
+        {
+            string validSession = HttpContext.Session.GetByRedis<string>("valid");
+            if (String.IsNullOrEmpty(validSession) || !code.Trim().Equals(validSession, StringComparison.InvariantCultureIgnoreCase))
+            {
+                return ResultData(null, false, "验证码错误");
+            }
+            return ResultData(null, false, "验证码正确");
+        }
+
+        /// <summary>
+        /// 获取用户信息
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetUserInfo()
+        {
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+#if DEBUG
+            user = UserInfoService.GetByUsername("masuit").Mapper<UserInfoOutputDto>();
+#endif
+            return ResultData(user);
+        }
+
+        /// <summary>
+        /// 注销登录
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult Logout()
+        {
+            HttpContext.Session.RemoveByRedis(SessionKey.UserInfo);
+            Response.Cookies.Delete("username");
+            Response.Cookies.Delete("password");
+            HttpContext.Session.Clear();
+            if (Request.Method.ToLower().Equals("get"))
+            {
+                return RedirectToAction("Index", "Home");
+            }
+            return ResultData(null, message: "注销成功!");
+        }
+    }
+}

+ 350 - 149
src/Masuit.MyBlogs.WebApp/Controllers/PostController.cs → src/Masuit.MyBlogs.Core/Controllers/PostController.cs

@@ -1,62 +1,87 @@
 using AutoMapper;
 using Common;
+using EFSecondLevelCache.Core;
 using Hangfire;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
-using Masuit.MyBlogs.WebApp.Models.Hangfire;
+using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Configs;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Extensions.Hangfire;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.Tools;
+using Masuit.Tools.Core.Net;
 using Masuit.Tools.DateTimeExt;
 using Masuit.Tools.Html;
-using Masuit.Tools.Net;
 using Masuit.Tools.Security;
 using Masuit.Tools.Systems;
-using Models.DTO;
-using Models.Entity;
-using Models.Enum;
-using Models.ViewModel;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.Net.Http.Headers;
 using System;
 using System.Collections.Generic;
-using System.Configuration;
 using System.IO;
 using System.Linq;
 using System.Text.RegularExpressions;
-using System.Web.Mvc;
-using static Common.CommonHelper;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 文章管理
+    /// </summary>
     public class PostController : BaseController
     {
-        private IPostBll PostBll { get; set; }
-        private ICategoryBll CategoryBll { get; set; }
-        private IBroadcastBll BroadcastBll { get; set; }
-        private ISeminarBll SeminarBll { get; set; }
-        private IPostAccessRecordBll PostAccessRecordBll { get; set; }
-        public ICommentBll CommentBll { get; set; }
-        public IPostHistoryVersionBll PostHistoryVersionBll { get; set; }
+        private IPostService PostService { get; set; }
+        private ICategoryService CategoryService { get; set; }
+        private IBroadcastService BroadcastService { get; set; }
+        private ISeminarService SeminarService { get; set; }
 
-        public PostController(IPostBll postBll, ICategoryBll categoryBll, IBroadcastBll broadcastBll, ISeminarBll seminarBll, IPostAccessRecordBll postAccessRecordBll, ICommentBll commentBll, IPostHistoryVersionBll postHistoryVersionBll)
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public IPostHistoryVersionService PostHistoryVersionService { get; set; }
+
+        /// <summary>
+        /// 文章管理
+        /// </summary>
+        /// <param name="postService"></param>
+        /// <param name="categoryService"></param>
+        /// <param name="broadcastService"></param>
+        /// <param name="seminarService"></param>
+        /// <param name="postHistoryVersionService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public PostController(IPostService postService, ICategoryService categoryService, IBroadcastService broadcastService, ISeminarService seminarService, IPostHistoryVersionService postHistoryVersionService, IHostingEnvironment hostingEnvironment)
         {
-            PostBll = postBll;
-            CategoryBll = categoryBll;
-            BroadcastBll = broadcastBll;
-            SeminarBll = seminarBll;
-            PostAccessRecordBll = postAccessRecordBll;
-            CommentBll = commentBll;
-            PostHistoryVersionBll = postHistoryVersionBll;
+            PostService = postService;
+            CategoryService = categoryService;
+            BroadcastService = broadcastService;
+            SeminarService = seminarService;
+            PostHistoryVersionService = postHistoryVersionService;
+            _hostingEnvironment = hostingEnvironment;
         }
 
+        /// <summary>
+        /// 文章详情页
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="kw"></param>
+        /// <returns></returns>
         [Route("{id:int}/{kw}"), Route("{id:int}")]
         public ActionResult Details(int id, string kw)
         {
-            Post post = PostBll.GetById(id);
+            Post post = PostService.GetById(id);
             if (post != null)
             {
                 ViewBag.Keyword = post.Keyword + "," + post.Label;
-                UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+                UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
                 DateTime modifyDate = post.ModifyDate;
-                ViewBag.Next = PostBll.GetFirstEntityFromL2CacheNoTracking(p => p.ModifyDate > modifyDate && (p.Status == Status.Pended || user.IsAdmin), p => p.ModifyDate);
-                ViewBag.Prev = PostBll.GetFirstEntityFromL2CacheNoTracking(p => p.ModifyDate < modifyDate && (p.Status == Status.Pended || user.IsAdmin), p => p.ModifyDate, false);
+                ViewBag.Next = PostService.GetFirstEntityFromL2CacheNoTracking(p => p.ModifyDate > modifyDate && (p.Status == Status.Pended || user.IsAdmin), p => p.ModifyDate);
+                ViewBag.Prev = PostService.GetFirstEntityFromL2CacheNoTracking(p => p.ModifyDate < modifyDate && (p.Status == Status.Pended || user.IsAdmin), p => p.ModifyDate, false);
                 if (user.IsAdmin)
                 {
                     return View("Details_Admin", post);
@@ -67,10 +92,10 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     return RedirectToAction("Post", "Home");
                 }
 
-                if (string.IsNullOrEmpty(Session.GetByRedis<string>("post" + id)))
+                if (string.IsNullOrEmpty(HttpContext.Session.GetByRedis<string>("post" + id)))
                 {
                     HangfireHelper.CreateJob(typeof(IHangfireBackJob), nameof(HangfireBackJob.RecordPostVisit), args: id);
-                    Session.SetByRedis("post" + id, id.ToString());
+                    HttpContext.Session.SetByRedis("post" + id, id.ToString());
                 }
                 return View(post);
             }
@@ -88,11 +113,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Route("{id:int}/history"), Route("{id:int}/history/{page:int}/{size:int}")]
         public ActionResult History(int id, int page = 1, int size = 20)
         {
-            var p = PostBll.GetById(id).Mapper<PostOutputDto>();
+            var p = PostService.GetById(id).Mapper<PostOutputDto>();
             if (p != null)
             {
                 ViewBag.Primary = p;
-                var list = PostHistoryVersionBll.LoadPageEntitiesFromCacheNoTracking(page, size, out int total, v => v.PostId == id, v => v.ModifyDate, false).Select(v => new PostHistoryVersion()
+                var list = PostHistoryVersionService.LoadPageEntitiesNoTracking(page, size, out int total, v => v.PostId == id, v => v.ModifyDate, false).Select(v => new PostHistoryVersion()
                 {
                     PostId = id,
                     Category = v.Category,
@@ -100,13 +125,13 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     Title = v.Title,
                     Id = v.Id,
                     CategoryId = v.CategoryId
-                }).ToList();
+                }).Cacheable().ToList();
                 ViewBag.Total = total;
                 ViewBag.PageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
                 return View(list);
             }
 
-            return Redirect(Request.UrlReferrer?.ToString() ?? "/error");
+            return Redirect(Request.Headers[HeaderNames.Referer].ToString());
         }
 
         /// <summary>
@@ -118,8 +143,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Route("{id:int}/history/{hid:int}")]
         public ActionResult HistoryVersion(int id, int hid)
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            var post = PostHistoryVersionBll.GetById(hid);
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            var post = PostHistoryVersionService.GetById(hid);
             if (post is null)
             {
                 return RedirectToAction("History", new
@@ -128,8 +153,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 });
             }
 
-            ViewBag.Next = PostHistoryVersionBll.GetFirstEntityFromL2CacheNoTracking(p => p.PostId == id && p.ModifyDate > post.ModifyDate, p => p.ModifyDate);
-            ViewBag.Prev = PostHistoryVersionBll.GetFirstEntityFromL2CacheNoTracking(p => p.PostId == id && p.ModifyDate < post.ModifyDate, p => p.ModifyDate, false);
+            ViewBag.Next = PostHistoryVersionService.GetFirstEntityFromL2CacheNoTracking(p => p.PostId == id && p.ModifyDate > post.ModifyDate, p => p.ModifyDate);
+            ViewBag.Prev = PostHistoryVersionService.GetFirstEntityFromL2CacheNoTracking(p => p.PostId == id && p.ModifyDate < post.ModifyDate, p => p.ModifyDate, false);
             if (user.IsAdmin)
             {
                 return View("HistoryVersion_Admin", post);
@@ -138,12 +163,19 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return View(post);
         }
 
+        /// <summary>
+        /// 版本对比
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="v1"></param>
+        /// <param name="v2"></param>
+        /// <returns></returns>
         [Route("{id:int}/history/{v1:int}-{v2:int}")]
         public ActionResult CompareVersion(int id, int v1, int v2)
         {
-            var main = PostBll.GetById(id).Mapper<PostHistoryVersion>();
-            var left = v1 <= 0 ? main : PostHistoryVersionBll.GetById(v1);
-            var right = v2 <= 0 ? main : PostHistoryVersionBll.GetById(v2);
+            var main = PostService.GetById(id).Mapper<PostHistoryVersion>();
+            var left = v1 <= 0 ? main : PostHistoryVersionService.GetById(v1);
+            var right = v2 <= 0 ? main : PostHistoryVersionService.GetById(v2);
             HtmlDiff.HtmlDiff diffHelper = new HtmlDiff.HtmlDiff(right.Content, left.Content);
             string diffOutput = diffHelper.Build();
             right.Content = Regex.Replace(Regex.Replace(diffOutput, "<ins.+?</ins>", string.Empty), @"<\w+></\w+>", string.Empty);
@@ -156,48 +188,62 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             });
         }
 
+        /// <summary>
+        /// 反对
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         public ActionResult VoteDown(int id)
         {
-            Post post = PostBll.GetById(id);
-            if (Session["post-vote" + id] != null)
+            Post post = PostService.GetById(id);
+            if (HttpContext.Session.Get<object>("post-vote" + id) != null)
             {
                 return ResultData(null, false, "您刚才已经投过票了,感谢您的参与!");
             }
 
             if (post != null)
             {
-                Session["post-vote" + id] = id;
+                HttpContext.Session.Set("post-vote" + id, id);
                 ++post.VoteDownCount;
-                PostBll.UpdateEntity(post);
-                bool b = PostBll.SaveChanges() > 0;
+                PostService.UpdateEntity(post);
+                bool b = PostService.SaveChanges() > 0;
                 return ResultData(null, b, b ? "投票成功!" : "投票失败!");
             }
 
             return ResultData(null, false, "非法操作");
         }
 
+        /// <summary>
+        /// 支持
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         public ActionResult VoteUp(int id)
         {
-            Post post = PostBll.GetById(id);
-            if (Session["post-vote" + id] != null)
+            Post post = PostService.GetById(id);
+            if (HttpContext.Session.Get<object>("post-vote" + id) != null)
             {
                 return ResultData(null, false, "您刚才已经投过票了,感谢您的参与!");
             }
 
             if (post != null)
             {
-                Session["post-vote" + id] = id;
+                HttpContext.Session.Set("post-vote" + id, id);
                 ++post.VoteUpCount;
-                bool b = PostBll.UpdateEntitySaved(post);
+                bool b = PostService.UpdateEntitySaved(post);
                 return ResultData(null, b, b ? "投票成功!" : "投票失败!");
             }
 
             return ResultData(null, false, "非法操作");
         }
 
+        /// <summary>
+        /// 投稿页
+        /// </summary>
+        /// <returns></returns>
         public ActionResult Publish()
         {
-            List<string> list = PostBll.GetAll().Select(p => p.Label).ToList();
+            List<string> list = PostService.GetAll().Select(p => p.Label).ToList();
             List<string> result = new List<string>();
             list.ForEach(s =>
             {
@@ -206,8 +252,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     result.AddRange(s.Split(',', ','));
                 }
             });
-            ViewBag.Category = CategoryBll.LoadEntitiesNoTracking(c => c.Status == Status.Available).ToList();
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            ViewBag.Category = CategoryService.LoadEntitiesNoTracking(c => c.Status == Status.Available).ToList();
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
             if (user != null)
             {
                 return View("Publish_Admin", result.Distinct().OrderBy(s => s));
@@ -216,11 +262,16 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return View(result.Distinct().OrderBy(s => s));
         }
 
-        [HttpPost, ValidateAntiForgeryToken, ValidateInput(false)]
+        /// <summary>
+        /// 发布投稿
+        /// </summary>
+        /// <param name="post"></param>
+        /// <returns></returns>
+        [HttpPost, ValidateAntiForgeryToken]
         public ActionResult Publish(PostInputDto post)
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
-            if (!CategoryBll.Any(c => c.Id == post.CategoryId && c.Status == Status.Available))
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo);
+            if (!CategoryService.Any(c => c.Id == post.CategoryId && c.Status == Status.Available))
             {
                 return ResultData(null, message: "请选择一个分类");
             }
@@ -248,28 +299,28 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             }
             else
             {
-                post.Content = ReplaceImgSrc(Regex.Replace(post.Content.HtmlSantinizerStandard(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
+                post.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(post.Content.HtmlSantinizerStandard(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
             }
 
-            ViewBag.CategoryId = new SelectList(CategoryBll.LoadEntitiesNoTracking(c => c.Status == Status.Available), "Id", "Name", post.CategoryId);
+            ViewBag.CategoryId = new SelectList(CategoryService.LoadEntitiesNoTracking(c => c.Status == Status.Available), "Id", "Name", post.CategoryId);
             Post p = post.Mapper<Post>();
             p.PostAccessRecord.Add(new PostAccessRecord()
             {
                 AccessTime = DateTime.Today,
                 ClickCount = 0
             });
-            p = PostBll.AddEntitySaved(p);
+            p = PostService.AddEntitySaved(p);
             if (p != null)
             {
                 if (p.Status == Status.Pending)
                 {
-                    var email = GetSettings("ReceiveEmail");
+                    var email = CommonHelper.SystemSettings["ReceiveEmail"];
                     string link = Url.Action("Details", "Post", new
                     {
                         id = p.Id
-                    }, Request.Url?.Scheme ?? "http");
-                    string content = System.IO.File.ReadAllText(Request.MapPath("/template/publish.html")).Replace("{{link}}", link).Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{title}}", p.Title);
-                    BackgroundJob.Enqueue(() => SendMail(GetSettings("Title") + "有访客投稿:", content, email));
+                    }, Request.Scheme);
+                    string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/publish.html").Replace("{{link}}", link).Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{title}}", p.Title);
+                    BackgroundJob.Enqueue(() => CommonHelper.SendMail(CommonHelper.SystemSettings["Title"] + "有访客投稿:", content, email));
                     return ResultData(p.Mapper<PostOutputDto>(), message: "文章发表成功,待站长审核通过以后将显示到列表中!");
                 }
 
@@ -279,9 +330,13 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null, false, "文章发表失败!");
         }
 
+        /// <summary>
+        /// 获取标签
+        /// </summary>
+        /// <returns></returns>
         public ActionResult GetTag()
         {
-            List<string> list = PostBll.GetAll().Select(p => p.Label).ToList();
+            List<string> list = PostService.GetAll().Select(p => p.Label).ToList();
             List<string> result = new List<string>();
             list.ForEach(s =>
             {
@@ -293,11 +348,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(result.Distinct().OrderBy(s => s));
         }
 
+        /// <summary>
+        /// 标签云
+        /// </summary>
+        /// <returns></returns>
         [Route("all")]
         public ActionResult All()
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            List<string> tags = PostBll.GetAll().Select(p => p.Label).ToList(); //tag
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            List<string> tags = PostService.GetAll().Select(p => p.Label).ToList(); //tag
             List<string> result = new List<string>();
             tags.ForEach(s =>
             {
@@ -307,21 +366,26 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 }
             });
             ViewBag.tags = result.GroupBy(t => t).OrderByDescending(g => g.Count()).ThenBy(g => g.Key);
-            ViewBag.cats = CategoryBll.GetAll(c => c.Post.Count, false).Select(c => new TagCloudViewModel()
+            ViewBag.cats = CategoryService.GetAll(c => c.Post.Count, false).Select(c => new TagCloudViewModel()
             {
                 Id = c.Id,
                 Name = c.Name,
                 Count = c.Post.Count(p => p.Status == Status.Pended || user.IsAdmin)
             }).ToList(); //category
-            ViewBag.seminars = SeminarBll.GetAll(c => c.Post.Count, false).Select(c => new TagCloudViewModel
+            ViewBag.seminars = SeminarService.GetAll(c => c.Post.Count, false).Select(c => new TagCloudViewModel
             {
                 Id = c.Id,
                 Name = c.Title,
-                Count = c.Post.Count(p => p.Status == Status.Pended || user.IsAdmin)
+                Count = c.Post.Count(p => p.Post.Status == Status.Pended || user.IsAdmin)
             }).ToList(); //seminars
             return View();
         }
 
+        /// <summary>
+        /// 检查访问密码
+        /// </summary>
+        /// <param name="token"></param>
+        /// <returns></returns>
         [HttpPost, ValidateAntiForgeryToken]
         public ActionResult CheckViewToken(string token)
         {
@@ -333,13 +397,18 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             var s = RedisHelper.GetString("ArticleViewToken");
             if (token.Equals(s))
             {
-                Session.SetByRedis("ArticleViewToken", token);
+                HttpContext.Session.SetByRedis("ArticleViewToken", token);
                 return ResultData(null);
             }
 
             return ResultData(null, false, "文章访问密码不正确!");
         }
 
+        /// <summary>
+        /// 检查授权邮箱
+        /// </summary>
+        /// <param name="email"></param>
+        /// <returns></returns>
         [HttpPost, ValidateAntiForgeryToken]
         public ActionResult GetViewToken(string email)
         {
@@ -348,10 +417,10 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 return ResultData(null, false, "请输入正确的邮箱!");
             }
 
-            if (BroadcastBll.Any(b => b.Email.Equals(email) && b.SubscribeType == SubscribeType.ArticleToken))
+            if (BroadcastService.Any(b => b.Email.Equals(email) && b.SubscribeType == SubscribeType.ArticleToken))
             {
                 var s = RedisHelper.GetString("ArticleViewToken");
-                Session.SetByRedis("ArticleViewToken", s);
+                HttpContext.Session.SetByRedis("ArticleViewToken", s);
                 return ResultData(null);
             }
 
@@ -360,12 +429,17 @@ namespace Masuit.MyBlogs.WebApp.Controllers
 
         #region 后端管理
 
+        /// <summary>
+        /// 固顶
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Fixtop(int id)
         {
-            Post post = PostBll.GetById(id);
+            Post post = PostService.GetById(id);
             post.IsFixedTop = !post.IsFixedTop;
-            bool b = PostBll.UpdateEntitySaved(post);
+            bool b = PostService.UpdateEntitySaved(post);
             if (b)
             {
                 return ResultData(null, true, post.IsFixedTop ? "置顶成功!" : "取消置顶成功!");
@@ -374,58 +448,78 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null, false, "操作失败!");
         }
 
+        /// <summary>
+        /// 审核
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Pass(int id)
         {
-            Post post = PostBll.GetById(id);
+            Post post = PostService.GetById(id);
             post.Status = Status.Pended;
             post.ModifyDate = DateTime.Now;
             post.PostDate = DateTime.Now;
-            bool b = PostBll.UpdateEntitySaved(post);
-            if ("false" == GetSettings("DisabledEmailBroadcast"))
+            bool b = PostService.UpdateEntitySaved(post);
+            if ("false" == CommonHelper.SystemSettings["DisabledEmailBroadcast"])
             {
-                var cast = BroadcastBll.LoadEntities(c => c.Status == Status.Subscribed).ToList();
-                string link = Request.Url?.Scheme + "://" + Request.Url?.Authority + "/" + id;
+                var cast = BroadcastService.LoadEntities(c => c.Status == Status.Subscribed).ToList();
+                string link = Request.Scheme + "://" + Request.Host + "/" + id;
                 cast.ForEach(c =>
                 {
                     var ts = DateTime.Now.GetTotalMilliseconds();
-                    string content = System.IO.File.ReadAllText(Request.MapPath("/template/broadcast.html")).Replace("{{link}}", link + "?email=" + c.Email).Replace("{{time}}", post.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{title}}", post.Title).Replace("{{author}}", post.Author).Replace("{{content}}", post.Content.RemoveHtmlTag(150)).Replace("{{cancel}}", Url.Action("Subscribe", "Subscribe", new
+                    string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/broadcast.html").Replace("{{link}}", link + "?email=" + c.Email).Replace("{{time}}", post.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{title}}", post.Title).Replace("{{author}}", post.Author).Replace("{{content}}", post.Content.RemoveHtmlTag(150)).Replace("{{cancel}}", Url.Action("Subscribe", "Subscribe", new
                     {
                         c.Email,
                         act = "cancel",
                         validate = c.ValidateCode,
                         timespan = ts,
-                        hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(ConfigurationManager.AppSettings["BaiduAK"])
-                    }, Request.Url.Scheme));
-                    BackgroundJob.Enqueue(() => SendMail(GetSettings("Title") + "博客有新文章发布了", content, c.Email));
+                        hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(AppConfig.BaiduAK)
+                    }, Request.Scheme));
+                    BackgroundJob.Enqueue(() => CommonHelper.SendMail(CommonHelper.SystemSettings["Title"] + "博客有新文章发布了", content, c.Email));
                 });
             }
 
             return ResultData(null, b, b ? "审核通过!" : "审核失败!");
         }
 
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Delete(int id)
         {
-            var post = PostBll.GetById(id);
+            var post = PostService.GetById(id);
             post.Status = Status.Deleted;
-            bool b = PostBll.UpdateEntitySaved(post);
+            bool b = PostService.UpdateEntitySaved(post);
             return ResultData(null, b, b ? "删除成功!" : "删除失败!");
         }
 
+        /// <summary>
+        /// 还原版本
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Restore(int id)
         {
-            var post = PostBll.GetById(id);
+            var post = PostService.GetById(id);
             post.Status = Status.Pended;
-            bool b = PostBll.UpdateEntitySaved(post);
+            bool b = PostService.UpdateEntitySaved(post);
             return ResultData(null, b, b ? "恢复成功!" : "恢复失败!");
         }
 
+        /// <summary>
+        /// 彻底删除文章
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult Truncate(int id)
         {
-            var post = PostBll.GetById(id);
+            var post = PostService.GetById(id);
             if (post is null)
             {
                 return ResultData(null, false, "文章已经被删除!");
@@ -435,8 +529,8 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             {
                 try
                 {
-                    System.IO.File.Delete(Path.Combine(Server.MapPath("/upload"), post.ResourceName));
-                    Directory.Delete(Path.Combine(Server.MapPath("/upload"), Path.GetFileNameWithoutExtension(post.ResourceName)), true);
+                    System.IO.File.Delete(Path.Combine(_hostingEnvironment.WebRootPath + "/upload", post.ResourceName));
+                    Directory.Delete(Path.Combine(_hostingEnvironment.WebRootPath + "/upload", Path.GetFileNameWithoutExtension(post.ResourceName)), true);
                 }
                 catch (IOException)
                 {
@@ -450,7 +544,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 {
                     try
                     {
-                        System.IO.File.Delete(Path.Combine(Server.MapPath("/"), path));
+                        System.IO.File.Delete(_hostingEnvironment.WebRootPath + path);
                     }
                     catch (IOException)
                     {
@@ -458,7 +552,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 }
             }
 
-            bool b = PostBll.DeleteByIdSaved(id);
+            bool b = PostService.DeleteByIdSaved(id);
             return ResultData(null, b, b ? "删除成功!" : "删除失败!");
         }
 
@@ -470,14 +564,19 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Authority]
         public ActionResult Get(int id)
         {
-            Post post = PostBll.GetById(id);
+            Post post = PostService.GetById(id);
             PostOutputDto model = post.Mapper<PostOutputDto>();
-            model.Seminars = string.Join(",", post.Seminar.Select(s => s.Title));
+            model.Seminars = string.Join(",", post.Seminar.Select(s => s.Seminar.Title));
             return ResultData(model);
         }
 
+        /// <summary>
+        /// 文章详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
-        public ActionResult Read(int id) => ResultData(PostBll.GetById(id).Mapper<PostOutputDto>());
+        public ActionResult Read(int id) => ResultData(PostService.GetById(id).Mapper<PostOutputDto>());
 
         /// <summary>
         /// 获取所有文章
@@ -485,7 +584,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// <returns></returns>
         public ActionResult GetAllData()
         {
-            var plist = PostBll.LoadEntitiesNoTracking(p => p.Status != Status.Deleted).OrderBy(p => p.Status).ThenByDescending(p => p.IsFixedTop).ThenByDescending(p => p.ModifyDate).Select(p => new
+            var plist = PostService.LoadEntitiesNoTracking(p => p.Status != Status.Deleted).OrderBy(p => p.Status).ThenByDescending(p => p.IsFixedTop).ThenByDescending(p => p.ModifyDate).Select(p => new
             {
                 p.Id,
                 p.Author,
@@ -531,7 +630,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
 
             var list = new List<PostDataModel>();
             IOrderedQueryable<Post> temp;
-            var query = string.IsNullOrEmpty(kw) ? PostBll.GetAllNoTracking() : PostBll.LoadEntitiesNoTracking(p => p.Title.Contains(kw) || p.Author.Contains(kw) || p.Email.Contains(kw) || p.Label.Contains(kw) || p.Content.Contains(kw));
+            var query = string.IsNullOrEmpty(kw) ? PostService.GetAllNoTracking() : PostService.LoadEntitiesNoTracking(p => p.Title.Contains(kw) || p.Author.Contains(kw) || p.Email.Contains(kw) || p.Label.Contains(kw) || p.Content.Contains(kw));
             var total = query.Count();
             var order = query.OrderByDescending(p => p.Status).ThenByDescending(p => p.IsFixedTop);
             switch (orderby)
@@ -586,6 +685,13 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return PageResult(list, pageCount, total);
         }
 
+        /// <summary>
+        /// 获取未审核文章
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="search"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult GetPending(int page = 1, int size = 10, string search = "")
         {
@@ -593,11 +699,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             IQueryable<Post> temp;
             if (string.IsNullOrEmpty(search))
             {
-                temp = PostBll.LoadPageEntitiesNoTracking(page, size, out total, p => p.Status == Status.Pending, p => p.Id);
+                temp = PostService.LoadPageEntitiesNoTracking(page, size, out total, p => p.Status == Status.Pending, p => p.Id);
             }
             else
             {
-                temp = PostBll.LoadPageEntitiesNoTracking(page, size, out total, p => p.Status == Status.Pending && (p.Title.Contains(search) || p.Author.Contains(search) || p.Email.Contains(search) || p.Label.Contains(search)), p => p.Id);
+                temp = PostService.LoadPageEntitiesNoTracking(page, size, out total, p => p.Status == Status.Pending && (p.Title.Contains(search) || p.Author.Contains(search) || p.Email.Contains(search) || p.Label.Contains(search)), p => p.Id);
             }
 
             var plist = temp.OrderByDescending(p => p.IsFixedTop).ThenByDescending(p => p.ModifyDate).Select(p => new
@@ -629,11 +735,18 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return PageResult(list, pageCount, total);
         }
 
-        [HttpPost, Authority, ValidateInput(false)]
+        /// <summary>
+        /// 编辑
+        /// </summary>
+        /// <param name="post"></param>
+        /// <param name="notify"></param>
+        /// <param name="reserve"></param>
+        /// <returns></returns>
+        [HttpPost, Authority]
         public ActionResult Edit(PostInputDto post, bool notify = true, bool reserve = true)
         {
-            post.Content = ReplaceImgSrc(Regex.Replace(post.Content.Trim(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
-            if (!CategoryBll.Any(c => c.Id == post.CategoryId && c.Status == Status.Available))
+            post.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(post.Content.Trim(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/");
+            if (!CategoryService.Any(c => c.Id == post.CategoryId && c.Status == Status.Available))
             {
                 return ResultData(null, message: "请选择一个分类");
             }
@@ -662,11 +775,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 post.ProtectContent = null;
             }
 
-            Post p = PostBll.GetById(post.Id);
+            Post p = PostService.GetById(post.Id);
             if (reserve)
             {
                 post.ModifyDate = DateTime.Now;
                 var history = p.Mapper<PostHistoryVersion>();
+                history.Id = 0;
                 p.PostHistoryVersion.Add(history);
             }
 
@@ -677,22 +791,29 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 p.Seminar.Clear();
                 tmp.ForEach(s =>
                 {
-                    p.Seminar.Add(SeminarBll.GetFirstEntity(e => e.Title.Equals(s)));
+                    Seminar seminar = SeminarService.GetFirstEntity(e => e.Title.Equals(s));
+                    p.Seminar.Add(new SeminarPost()
+                    {
+                        Post = p,
+                        Seminar = seminar,
+                        PostId = p.Id,
+                        SeminarId = seminar.Id
+                    });
                 });
             }
 
-            bool b = PostBll.UpdateEntitySaved(p);
+            bool b = PostService.UpdateEntitySaved(p);
             if (b)
             {
 #if !DEBUG
-                if (notify && "false" == GetSettings("DisabledEmailBroadcast"))
+                if (notify && "false" == CommonHelper.SystemSettings["DisabledEmailBroadcast"])
                 {
-                    var cast = BroadcastBll.LoadEntities(c => c.Status == Status.Subscribed).ToList();
-                    string link = Request.Url?.Scheme + "://" + Request.Url?.Authority + "/" + p.Id;
+                    var cast = BroadcastService.LoadEntities(c => c.Status == Status.Subscribed).ToList();
+                    string link = Request.Scheme + "://" + Request.Host + "/" + p.Id;
                     cast.ForEach(c =>
                     {
                         var ts = DateTime.Now.GetTotalMilliseconds();
-                        string content = System.IO.File.ReadAllText(Request.MapPath("/template/broadcast.html"))
+                        string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + ("template/broadcast.html"))
                             .Replace("{{link}}", link + "?email=" + c.Email)
                             .Replace("{{time}}", post.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss"))
                             .Replace("{{title}}", post.Title)
@@ -704,9 +825,9 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                                 act = "cancel",
                                 validate = c.ValidateCode,
                                 timespan = ts,
-                                hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(ConfigurationManager.AppSettings["BaiduAK"])
-                            }, Request.Url.Scheme));
-                        BackgroundJob.Schedule(() => SendMail(GetSettings("Title") + "博客有新文章发布了", content, c.Email), (p.ModifyDate - DateTime.Now));
+                                hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(AppConfig.BaiduAK)
+                            }, Request.Scheme));
+                        BackgroundJob.Schedule(() => CommonHelper.SendMail(CommonHelper.SystemSettings["Title"] + "博客有新文章发布了", content, c.Email), (p.ModifyDate - DateTime.Now));
                     });
                 }
 #endif
@@ -716,11 +837,18 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null, false, "文章修改失败!");
         }
 
-        [Authority, ValidateInput(false), HttpPost]
+        /// <summary>
+        /// 发布
+        /// </summary>
+        /// <param name="post"></param>
+        /// <param name="timespan"></param>
+        /// <param name="schedule"></param>
+        /// <returns></returns>
+        [Authority, HttpPost]
         public ActionResult Write(PostInputDto post, DateTime? timespan, bool schedule = false)
         {
-            post.Content = ReplaceImgSrc(Regex.Replace(post.Content.Trim(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/"); //提取img标签,提取src属性并重新创建个只包含src属性的img标签
-            if (!CategoryBll.Any(c => c.Id == post.CategoryId && c.Status == Status.Available))
+            post.Content = CommonHelper.ReplaceImgSrc(Regex.Replace(post.Content.Trim(), @"<img\s+[^>]*\s*src\s*=\s*['""]?(\S+\.\w{3,4})['""]?[^/>]*/>", "<img src=\"$1\"/>")).Replace("/thumb150/", "/large/"); //提取img标签,提取src属性并重新创建个只包含src属性的img标签
+            if (!CategoryService.Any(c => c.Id == post.CategoryId && c.Status == Status.Available))
             {
                 return ResultData(null, message: "请选择一个分类");
             }
@@ -759,7 +887,14 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 tmp.ForEach(s =>
                 {
                     var id = s.ToInt32();
-                    p.Seminar.Add(SeminarBll.GetById(id));
+                    Seminar seminar = SeminarService.GetById(id);
+                    p.Seminar.Add(new SeminarPost()
+                    {
+                        Post = p,
+                        PostId = p.Id,
+                        Seminar = seminar,
+                        SeminarId = seminar.Id
+                    });
                 });
             }
 
@@ -782,25 +917,25 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 return ResultData(null, false, "如果要定时发布,请选择正确的一个将来时间点!");
             }
 
-            p = PostBll.AddEntitySaved(p);
+            p = PostService.AddEntitySaved(p);
             if (p != null)
             {
-                if ("false" == GetSettings("DisabledEmailBroadcast"))
+                if ("false" == CommonHelper.SystemSettings["DisabledEmailBroadcast"])
                 {
-                    var cast = BroadcastBll.LoadEntities(c => c.Status == Status.Subscribed).ToList();
-                    string link = Request.Url?.Scheme + "://" + Request.Url?.Authority + "/" + p.Id;
+                    var cast = BroadcastService.LoadEntities(c => c.Status == Status.Subscribed).ToList();
+                    string link = Request.Scheme + "://" + Request.Host + "/" + p.Id;
                     cast.ForEach(c =>
                     {
                         var ts = DateTime.Now.GetTotalMilliseconds();
-                        string content = System.IO.File.ReadAllText(Request.MapPath("/template/broadcast.html")).Replace("{{link}}", link + "?email=" + c.Email).Replace("{{time}}", post.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{title}}", post.Title).Replace("{{author}}", post.Author).Replace("{{content}}", post.Content.RemoveHtmlTag(150)).Replace("{{cancel}}", Url.Action("Subscribe", "Subscribe", new
+                        string content = System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/broadcast.html").Replace("{{link}}", link + "?email=" + c.Email).Replace("{{time}}", post.ModifyDate.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{title}}", post.Title).Replace("{{author}}", post.Author).Replace("{{content}}", post.Content.RemoveHtmlTag(150)).Replace("{{cancel}}", Url.Action("Subscribe", "Subscribe", new
                         {
                             c.Email,
                             act = "cancel",
                             validate = c.ValidateCode,
                             timespan = ts,
-                            hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(ConfigurationManager.AppSettings["BaiduAK"])
-                        }, Request.Url.Scheme));
-                        BackgroundJob.Schedule(() => SendMail(GetSettings("Title") + "博客有新文章发布了", content, c.Email), (p.ModifyDate - DateTime.Now));
+                            hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(AppConfig.BaiduAK)
+                        }, Request.Scheme));
+                        BackgroundJob.Schedule(() => CommonHelper.SendMail(CommonHelper.SystemSettings["Title"] + "博客有新文章发布了", content, c.Email), (p.ModifyDate - DateTime.Now));
                     });
                 }
 
@@ -816,7 +951,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// <returns></returns>
         public ActionResult GetTops()
         {
-            var list = PostBll.LoadEntitiesNoTracking<DateTime, PostOutputDto>(p => p.Status == Status.Pended && p.IsBanner, p => p.ModifyDate, false).Select(p => new
+            var list = PostService.LoadEntities<DateTime, PostOutputDto>(p => p.Status == Status.Pended && p.IsBanner, p => p.ModifyDate, false).Select(p => new
             {
                 p.Id,
                 p.Description,
@@ -832,7 +967,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// <returns></returns>
         public ActionResult GetNotTops()
         {
-            var list = PostBll.LoadEntitiesNoTracking(p => p.Status == Status.Pended && !p.IsBanner).GroupBy(p => p.Category.Name).Select(g => new
+            var list = PostService.LoadEntitiesNoTracking(p => p.Status == Status.Pended && !p.IsBanner).GroupBy(p => p.Category.Name).Select(g => new
             {
                 text = g.Key,
                 children = g.OrderBy(p => p.Title).Select(p => new
@@ -849,14 +984,14 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// </summary>
         /// <param name="p"></param>
         /// <returns></returns>
-        [HttpPost, ValidateInput(false), Authority]
+        [HttpPost, Authority]
         public ActionResult AddTop(PostOutputDto p)
         {
-            Post post = PostBll.GetById(p.Id);
+            Post post = PostService.GetById(p.Id);
             post.IsBanner = true;
             post.Description = p.Description;
             post.ImageUrl = p.ImageUrl;
-            bool b = PostBll.UpdateEntitySaved(post);
+            bool b = PostService.UpdateEntitySaved(post);
             return ResultData(null, b, b ? "添加头图页成功" : "添加头图页失败!");
         }
 
@@ -868,39 +1003,72 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Authority, HttpPost]
         public ActionResult RemoveTop(int id)
         {
-            Post post = PostBll.GetById(id);
+            Post post = PostService.GetById(id);
             post.IsBanner = false;
-            bool b = PostBll.UpdateEntitySaved(post);
+            bool b = PostService.UpdateEntitySaved(post);
             return ResultData(null, b, b ? "取消头图页成功" : "取消头图页失败!");
         }
 
+        /// <summary>
+        /// 添加专题
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="sid"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult AddSeminar(int id, int sid)
         {
-            var post = PostBll.GetById(id);
-            Seminar seminar = SeminarBll.GetById(sid);
-            post.Seminar.Add(seminar);
-            bool b = PostBll.UpdateEntitySaved(post);
+            var post = PostService.GetById(id);
+            Seminar seminar = SeminarService.GetById(sid);
+            post.Seminar.Add(new SeminarPost()
+            {
+                Post = post,
+                Seminar = seminar,
+                SeminarId = seminar.Id,
+                PostId = post.Id
+            });
+            bool b = PostService.UpdateEntitySaved(post);
             return ResultData(null, b, b ? $"已将文章【{post.Title}】添加到专题【{seminar.Title}】" : "添加失败");
         }
 
+        /// <summary>
+        /// 移除专题
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="sid"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult RemoveSeminar(int id, int sid)
         {
-            var post = PostBll.GetById(id);
-            Seminar seminar = SeminarBll.GetById(sid);
-            post.Seminar.Remove(seminar);
-            bool b = PostBll.UpdateEntitySaved(post);
+            var post = PostService.GetById(id);
+            Seminar seminar = SeminarService.GetById(sid);
+            post.Seminar.Remove(new SeminarPost()
+            {
+                Post = post,
+                Seminar = seminar,
+                SeminarId = seminar.Id,
+                PostId = post.Id
+            });
+            bool b = PostService.UpdateEntitySaved(post);
             return ResultData(null, b, b ? $"已将文章【{post.Title}】从【{seminar.Title}】专题移除" : "添加失败");
         }
 
+        /// <summary>
+        /// 删除历史版本
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [Authority]
         public ActionResult DeleteHistory(int id)
         {
-            bool b = PostHistoryVersionBll.DeleteByIdSaved(id);
+            bool b = PostHistoryVersionService.DeleteByIdSaved(id);
             return ResultData(null, b, b ? "历史版本文章删除成功!" : "历史版本文章删除失败!");
         }
 
+        /// <summary>
+        /// 获取文章访问密码
+        /// </summary>
+        /// <returns></returns>
         [Authority, HttpPost]
         public ActionResult ViewToken()
         {
@@ -913,34 +1081,67 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(token);
         }
 
+        /// <summary>
+        /// 还原版本
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         public ActionResult Revert(int id)
         {
-            var history = PostHistoryVersionBll.GetById(id);
+            var history = PostHistoryVersionService.GetById(id);
             if (history != null)
             {
-                PostHistoryVersionBll.AddEntity(history.Post.Mapper<PostHistoryVersion>());
+                var version = history.Post.Mapper<PostHistoryVersion>();
+                version.Id = 0;
+                PostHistoryVersionService.AddEntity(version);
                 history.Post.Category = history.Category;
                 history.Post.CategoryId = history.CategoryId;
                 history.Post.Content = history.Content;
                 history.Post.Title = history.Title;
                 history.Post.Label = history.Label;
-                history.Post.Seminar = history.Seminar;
+                history.Post.Seminar.Clear();
+                foreach (var s in history.Seminar)
+                {
+                    history.Post.Seminar.Add(new SeminarPost()
+                    {
+                        Post = history.Post,
+                        PostId = history.PostId,
+                        Seminar = s.Seminar,
+                        SeminarId = s.SeminarId
+                    });
+                }
                 history.Post.ModifyDate = history.ModifyDate;
-                bool b = PostHistoryVersionBll.UpdateEntitySaved(history);
+                bool b = PostHistoryVersionService.UpdateEntitySaved(history);
                 return ResultData(null, b, b ? "回滚成功" : "回滚失败");
             }
 
             return ResultData(null, false, "版本不存在");
         }
 
+        /// <summary>
+        /// 文章分析
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [HttpPost]
         public ActionResult Analyse(int id)
         {
-            var list = PostBll.GetById(id).PostAccessRecord.OrderBy(r => r.AccessTime).GroupBy(r => r.AccessTime.Date).Select(r => new[] { r.Key.GetTotalMilliseconds(), r.Sum(p => p.ClickCount) }).ToList();
+            var list = PostService.GetById(id).PostAccessRecord.OrderBy(r => r.AccessTime).GroupBy(r => r.AccessTime.Date).Select(r => new[]
+            {
+                r.Key.GetTotalMilliseconds(),
+                r.Sum(p => p.ClickCount)
+            }).ToList();
             var high = list.OrderByDescending(n => n[1]).FirstOrDefault();
             var average = list.Average(d => d[1]);
-            return ResultData(new { list, aver = average, high = high[1], highDate = DateTime.Parse("1970-01-01").AddMilliseconds(high[0]) });
+            return ResultData(new
+            {
+                list,
+                aver = average,
+                high = high[1],
+                highDate = DateTime.Parse("1970-01-01").AddMilliseconds(high[0])
+            });
         }
+
         #endregion
     }
 }

+ 38 - 33
src/Masuit.MyBlogs.WebApp/Controllers/PublicController.cs → src/Masuit.MyBlogs.Core/Controllers/PublicController.cs

@@ -1,33 +1,38 @@
-using System;
-using System.Configuration;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using System.Web;
-using System.Web.Http;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
+using Masuit.MyBlogs.Core.Configs;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.Tools;
+using Masuit.Tools.Core.Net;
 using Masuit.Tools.Models;
-using Masuit.Tools.Net;
-using Masuit.Tools.Win32;
-using Models.Enum;
+using Microsoft.AspNetCore.Mvc;
 using Newtonsoft.Json;
+using System;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+#if DEBUG
+using Masuit.Tools.Win32; 
+#endif
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
     /// <summary>
     /// 公共API
     /// </summary>
-    [Route("public/{action}"), WebApiExceptionFilter]
-    public class PublicController : ApiController
+    public class PublicController : Controller
     {
-        public IPostBll PostBll { get; set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public IPostService PostService { get; set; }
 
-        public PublicController(IPostBll postBll)
+        /// <summary>
+        /// 开放API
+        /// </summary>
+        /// <param name="postService"></param>
+        public PublicController(IPostService postService)
         {
-            PostBll = postBll;
+            PostService = postService;
         }
 
         /// <summary>
@@ -35,9 +40,9 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpGet, HttpPost, Route("subscribe/post")]
-        public IHttpActionResult Post()
+        public IActionResult Post()
         {
-            var list = PostBll.LoadPageEntitiesNoTracking(1, 10, out int _, p => p.Status == Status.Pended, p => p.ModifyDate, false).Select(p => new
+            var list = PostService.LoadPageEntitiesNoTracking(1, 10, out int _, p => p.Status == Status.Pended, p => p.ModifyDate, false).Select(p => new
             {
                 p.Id,
                 p.Title,
@@ -54,14 +59,14 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 p.ModifyDate,
                 Tags = p.Label,
                 p.Category,
-                Link = HttpContext.Current.Request.Url?.Scheme + "://" + HttpContext.Current.Request.Url?.Authority + "/" + p.Id
+                Link = Request.Scheme + "://" + Request.Host + "/" + p.Id
             }).ToList();
-            bool callback = string.IsNullOrEmpty(HttpContext.Current.Request["callback"]);
+            bool callback = string.IsNullOrEmpty(Request.Query["callback"]);
             if (callback)
             {
-                return Content(HttpStatusCode.OK, list);
+                return Ok(list);
             }
-            return Content(HttpStatusCode.OK, $"{HttpContext.Current.Request["callback"]}({list.ToJsonString()});");
+            return Ok($"{Request.Query["callback"]}({list.ToJsonString()});");
         }
 
         /// <summary>
@@ -70,12 +75,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// <param name="lat">纬度</param>
         /// <param name="lng">经度</param>
         /// <returns></returns>
-        [HttpPost, Route("tools/position")]
+        [HttpPost("tools/position")]
         public async Task<PhysicsAddress> Position(string lat, string lng)
         {
             if (string.IsNullOrEmpty(lat) || string.IsNullOrEmpty(lng))
             {
-                var ip = HttpContext.Current.Request.UserHostAddress;
+                var ip = HttpContext.Connection.RemoteIpAddress.ToString();
 #if DEBUG
                 Random r = new Random();
                 ip = $"{r.StrictNext(210)}.{r.StrictNext(255)}.{r.StrictNext(255)}.{r.StrictNext(255)}";
@@ -87,7 +92,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             {
                 BaseAddress = new Uri("http://api.map.baidu.com")
             };
-            string s = client.GetStringAsync($"/geocoder/v2/?location={lat},{lng}&output=json&pois=1&ak={ConfigurationManager.AppSettings["BaiduAK"]}").Result;
+            string s = client.GetStringAsync($"/geocoder/v2/?location={lat},{lng}&output=json&pois=1&ak={AppConfig.BaiduAK}").Result;
             PhysicsAddress physicsAddress = JsonConvert.DeserializeObject<PhysicsAddress>(s);
             return physicsAddress;
         }
@@ -97,12 +102,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// </summary>
         /// <param name="addr">详细地理信息</param>
         /// <returns></returns>
-        [HttpPost, Route("tools/address")]
+        [HttpPost("tools/address")]
         public async Task<Location> Address(string addr)
         {
             if (string.IsNullOrEmpty(addr))
             {
-                var ip = HttpContext.Current.Request.UserHostAddress;
+                var ip = HttpContext.Connection.RemoteIpAddress.ToString();
 #if DEBUG
                 Random r = new Random();
                 ip = $"{r.StrictNext(210)}.{r.StrictNext(255)}.{r.StrictNext(255)}.{r.StrictNext(255)}";
@@ -117,7 +122,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             {
                 BaseAddress = new Uri("http://api.map.baidu.com")
             };
-            string s = client.GetStringAsync($"/geocoder/v2/?output=json&address={addr}&ak={ConfigurationManager.AppSettings["BaiduAK"]}").Result;
+            string s = client.GetStringAsync($"/geocoder/v2/?output=json&address={addr}&ak={AppConfig.BaiduAK}").Result;
             var physicsAddress = JsonConvert.DeserializeAnonymousType(s, new
             {
                 status = 0,
@@ -134,12 +139,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         /// </summary>
         /// <param name="ip"></param>
         /// <returns></returns>
-        [HttpPost, Route("tools/ipinfo")]
+        [HttpPost("tools/ipinfo")]
         public async Task<PhysicsAddress> GetIpInfo(string ip)
         {
             if (string.IsNullOrEmpty(ip))
             {
-                ip = HttpContext.Current.Request.UserHostAddress;
+                ip = HttpContext.Connection.RemoteIpAddress.ToString();
             }
             PhysicsAddress address = await ip.GetPhysicsAddressInfo();
             return address;

+ 59 - 27
src/Masuit.MyBlogs.WebApp/Controllers/SearchController.cs → src/Masuit.MyBlogs.Core/Controllers/SearchController.cs

@@ -1,34 +1,50 @@
 using Common;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
 using Masuit.Tools.NoSQL;
-using Models.DTO;
-using Models.Entity;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Web.Mvc;
-using KeywordsRankOutputDto = Models.DTO.KeywordsRankOutputDto;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 站内搜索
+    /// </summary>
     public class SearchController : BaseController
     {
-        public ISearchDetailsBll SearchDetailsBll { get; set; }
-        private readonly IPostBll _postBll;
+        /// <summary>
+        /// 
+        /// </summary>
+        public ISearchDetailsService SearchDetailsService { get; set; }
+        private readonly IPostService _postService;
 
-        public SearchController(ISearchDetailsBll searchDetailsBll, IPostBll postBll)
+        /// <summary>
+        /// 站内搜索
+        /// </summary>
+        /// <param name="searchDetailsService"></param>
+        /// <param name="postService"></param>
+        public SearchController(ISearchDetailsService searchDetailsService, IPostService postService)
         {
-            SearchDetailsBll = searchDetailsBll;
-            _postBll = postBll;
+            SearchDetailsService = searchDetailsService;
+            _postService = postService;
         }
 
-        [Route("s/{wd?}/{page:int?}/{size:int?}"), OutputCache(VaryByParam = "wd", Duration = 60)]
-        public async Task<ActionResult> Search(string wd = "", int page = 1, int size = 10)
+        /// <summary>
+        /// 搜索页
+        /// </summary>
+        /// <param name="wd"></param>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        [Route("s/{wd?}/{page:int?}/{size:int?}"), ResponseCache(VaryByQueryKeys = new[] { "wd", "page", "size" }, Duration = 60)]
+        public ActionResult Search(string wd = "", int page = 1, int size = 10)
         {
             var nul = new List<PostOutputDto>();
             int count = 0;
@@ -43,12 +59,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             var start = DateTime.Today.AddDays(-7);
             using (RedisHelper redisHelper = RedisHelper.GetInstance())
             {
-                string key = Request.UserHostAddress + Request.UserAgent;
+                string key = HttpContext.Connection.Id;
                 if (redisHelper.KeyExists(key) && !redisHelper.GetString(key).Equals(wd))
                 {
-                    var hotSearches = (await SearchDetailsBll.LoadEntitiesFromCacheNoTrackingAsync(s => s.SearchTime > start, s => s.SearchTime, false)).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(7).Select(g => new KeywordsRankOutputDto()
+                    var hotSearches = SearchDetailsService.LoadEntitiesFromL2CacheNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(7).Select(g => new KeywordsRankOutputDto()
                     {
-                        KeyWords = g.FirstOrDefault()?.KeyWords,
+                        KeyWords = g.FirstOrDefault().KeyWords,
                         SearchCount = g.Count()
                     }).ToList();
                     ViewBag.hotSearches = hotSearches;
@@ -60,19 +76,19 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 {
                     if (page == 1)
                     {
-                        SearchDetailsBll.AddEntity(new SearchDetails()
+                        SearchDetailsService.AddEntity(new SearchDetails()
                         {
                             KeyWords = wd,
                             SearchTime = DateTime.Now,
-                            IP = Request.UserHostAddress
+                            IP = HttpContext.Connection.RemoteIpAddress.ToString()
                         });
                     }
                     string[] keywords = LuceneHelper.CutKeywords(wd).ToArray();
                     Stopwatch sw = Stopwatch.StartNew();
-                    var posts = _postBll.SearchPage(page, size, out count, keywords, p => p.ModifyDate);
+                    var posts = _postService.SearchPage(page, size, out count, keywords, p => p.ModifyDate);
                     ViewBag.Elapsed = sw.Elapsed.TotalMilliseconds;
                     ViewBag.Total = count;
-                    SearchDetailsBll.SaveChanges();
+                    SearchDetailsService.SaveChanges();
                     if (count > 1)
                     {
                         redisHelper.SetString(key, wd, TimeSpan.FromSeconds(10));
@@ -80,15 +96,22 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     ViewBag.hotSearches = new List<KeywordsRankOutputDto>();
                     return View(posts);
                 }
-                ViewBag.hotSearches = (await SearchDetailsBll.LoadEntitiesFromCacheNoTrackingAsync(s => s.SearchTime > start, s => s.SearchTime, false)).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(7).Select(g => new KeywordsRankOutputDto()
+                ViewBag.hotSearches = SearchDetailsService.LoadEntitiesFromL2CacheNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(7).Select(g => new KeywordsRankOutputDto()
                 {
-                    KeyWords = g.FirstOrDefault()?.KeyWords,
+                    KeyWords = g.FirstOrDefault().KeyWords,
                     SearchCount = g.Count()
                 }).ToList();
                 return View(nul);
             }
         }
 
+        /// <summary>
+        /// 关键词推荐
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="search"></param>
+        /// <returns></returns>
         [Authority, HttpPost]
         public ActionResult SearchList(int page = 1, int size = 10, string search = "")
         {
@@ -97,16 +120,20 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 page = 1;
             }
             var @where = string.IsNullOrEmpty(search) ? (Expression<Func<SearchDetails, bool>>)(s => true) : s => s.KeyWords.Contains(search);
-            var list = SearchDetailsBll.LoadPageEntitiesNoTracking<DateTime, SearchDetailsOutputDto>(page, size, out int total, where, s => s.SearchTime, false).ToList();
+            var list = SearchDetailsService.LoadPageEntities<DateTime, SearchDetailsOutputDto>(page, size, out int total, where, s => s.SearchTime, false).ToList();
             var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
             return PageResult(list, pageCount, total);
         }
 
+        /// <summary>
+        /// 热词
+        /// </summary>
+        /// <returns></returns>
         [Authority, HttpPost]
         public ActionResult HotKey()
         {
             var start = DateTime.Today.AddMonths(-1);
-            var temp = SearchDetailsBll.LoadEntitiesNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).ToList();
+            var temp = SearchDetailsService.LoadEntitiesNoTracking(s => s.SearchTime > start, s => s.SearchTime, false).ToList();
             var month = temp.GroupBy(s => s.KeyWords.ToLower()).OrderByDescending(g => g.Count()).Take(30).Select(g => new
             {
                 Keywords = g.FirstOrDefault().KeyWords,
@@ -130,10 +157,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             });
         }
 
+        /// <summary>
+        /// 删除搜索记录
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
         [HttpPost, Authority]
         public ActionResult Delete(int id)
         {
-            bool b = SearchDetailsBll.DeleteByIdSaved(id);
+            bool b = SearchDetailsService.DeleteByIdSaved(id);
             return ResultData(null, b, b ? "删除成功!" : "删除失败!");
         }
     }

+ 223 - 0
src/Masuit.MyBlogs.Core/Controllers/SeminarController.cs

@@ -0,0 +1,223 @@
+using Common;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 专题页
+    /// </summary>
+    public class SeminarController : BaseController
+    {
+        /// <summary>
+        /// 专题
+        /// </summary>
+        public ISeminarService SeminarService { get; set; }
+
+        /// <summary>
+        /// 文章
+        /// </summary>
+        public IPostService PostService { get; set; }
+
+        private readonly ISeminarPostService _seminarPostService;
+
+        /// <summary>
+        /// 专题页
+        /// </summary>
+        /// <param name="seminarService"></param>
+        /// <param name="postService"></param>
+        /// <param name="seminarPostService"></param>
+        public SeminarController(ISeminarService seminarService, IPostService postService, ISeminarPostService seminarPostService)
+        {
+            SeminarService = seminarService;
+            PostService = postService;
+            _seminarPostService = seminarPostService;
+        }
+
+        /// <summary>
+        /// 专题页
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="orderBy"></param>
+        /// <returns></returns>
+        [Route("c/{id:int}/{page:int?}/{size:int?}")]
+        public ActionResult Index(int id, int page = 1, int size = 15, OrderBy orderBy = OrderBy.ModifyDate)
+        {
+            IList<Post> posts;
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            var s = SeminarService.GetById(id);
+            if (s is null)
+            {
+                return RedirectToAction("Index", "Error");
+            }
+            var temp = PostService.LoadEntities(p => p.Seminar.Any(x => x.SeminarId == id) && (p.Status == Status.Pended || user.IsAdmin)).OrderByDescending(p => p.IsFixedTop);
+            switch (orderBy)
+            {
+                case OrderBy.CommentCount:
+                    posts = temp.ThenByDescending(p => p.Comment.Count).Skip(size * (page - 1)).Take(size).ToList();
+                    break;
+                case OrderBy.PostDate:
+                    posts = temp.ThenByDescending(p => p.PostDate).Skip(size * (page - 1)).Take(size).ToList();
+                    break;
+                case OrderBy.ViewCount:
+                    posts = temp.ThenByDescending(p => p.PostAccessRecord.Sum(r => r.ClickCount)).Skip(size * (page - 1)).Take(size).ToList();
+                    break;
+                case OrderBy.VoteCount:
+                    posts = temp.ThenByDescending(p => p.VoteUpCount).Skip(size * (page - 1)).Take(size).ToList();
+                    break;
+                default:
+                    posts = temp.ThenByDescending(p => p.ModifyDate).Skip(size * (page - 1)).Take(size).ToList();
+                    break;
+            }
+            ViewBag.Total = temp.Count();
+            ViewBag.Title = s.Title;
+            ViewBag.Desc = s.Description;
+            ViewBag.SubTitle = s.SubTitle;
+            return View(posts.Mapper<IList<PostOutputDto>>());
+        }
+
+        #region 管理端
+
+        /// <summary>
+        /// 保存专题
+        /// </summary>
+        /// <param name="seminar"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Save(Seminar seminar)
+        {
+            bool contain;
+            if (seminar.Id > 0)
+            {
+                //更新
+                contain = SeminarService.GetAll().Select(s => s.Title).Except(new List<string>()
+                {
+                    SeminarService.GetById(seminar.Id).Title
+                }).Contains(seminar.Title);
+            }
+            else
+            {
+                //添加
+                contain = SeminarService.GetAll().Select(s => s.Title).Contains(seminar.Title);
+            }
+            if (contain)
+            {
+                return ResultData(null, false, $"{seminar.Title} 已经存在了");
+            }
+            //var b = SeminarService.AddOrUpdateSaved(s => s.Id, seminar) > 0;
+            Seminar entry = SeminarService.GetById(seminar.Id);
+            bool b;
+            if (entry is null)
+            {
+                b = SeminarService.AddEntitySaved(seminar) != null;
+            }
+            else
+            {
+                entry.Description = seminar.Description;
+                entry.Title = seminar.Title;
+                entry.SubTitle = seminar.SubTitle;
+                b = SeminarService.UpdateEntitySaved(entry);
+            }
+            return ResultData(null, b, b ? "保存成功" : "保存失败");
+        }
+
+        /// <summary>
+        /// 删除专题
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Delete(int id)
+        {
+            bool b = SeminarService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除成功" : "删除失败");
+        }
+
+        /// <summary>
+        /// 获取专题详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Get(int id)
+        {
+            Seminar seminar = SeminarService.GetById(id);
+            return ResultData(seminar.Mapper<SeminarOutputDto>());
+        }
+
+        /// <summary>
+        /// 专题分页列表
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult GetPageData(int page, int size)
+        {
+            List<SeminarOutputDto> list = SeminarService.LoadPageEntities<int, SeminarOutputDto>(page, size, out int total, s => true, s => s.Id, false).ToList();
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+
+        /// <summary>
+        /// 获取所有专题
+        /// </summary>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult GetAll()
+        {
+            List<SeminarOutputDto> list = SeminarService.GetAll<string, SeminarOutputDto>(s => s.Title).ToList();
+            return ResultData(list);
+        }
+
+        /// <summary>
+        /// 给专题添加文章
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="pid"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult AddPost(int id, int pid)
+        {
+            Seminar seminar = SeminarService.GetById(id);
+            Post post = PostService.GetById(pid);
+            seminar.Post.Add(new SeminarPost()
+            {
+                Post = post,
+                Seminar = seminar,
+                PostId = post.Id,
+                SeminarId = id
+            });
+            bool b = SeminarService.UpdateEntitySaved(seminar);
+            return ResultData(null, b, b ? $"已成功将【{post.Title}】添加到专题【{seminar.Title}】" : "添加失败!");
+        }
+
+        /// <summary>
+        /// 移除文章
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="pid"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult RemovePost(int id, int pid)
+        {
+            Seminar seminar = SeminarService.GetById(id);
+            Post post = PostService.GetById(pid);
+            bool b = _seminarPostService.DeleteEntitySaved(s => s.SeminarId == id && s.PostId == pid) > 0;
+            return ResultData(null, b, b ? $"已成功将【{post.Title}】从专题【{seminar.Title}】移除" : "添加失败!");
+        }
+
+        #endregion
+    }
+}

+ 68 - 0
src/Masuit.MyBlogs.Core/Controllers/ShareController.cs

@@ -0,0 +1,68 @@
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Microsoft.AspNetCore.Mvc;
+using System.Linq;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 快速分享
+    /// </summary>
+    public class ShareController : AdminController
+    {
+        /// <summary>
+        /// 快速分享
+        /// </summary>
+        public IFastShareService FastShareService { get; set; }
+
+        /// <summary>
+        /// 快速分享
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult Index()
+        {
+            var shares = FastShareService.GetAll(s => s.Sort).ToList();
+            return ResultData(shares);
+        }
+
+        /// <summary>
+        /// 添加快速分享
+        /// </summary>
+        /// <param name="share"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult Add(FastShare share)
+        {
+            bool b = FastShareService.AddEntitySaved(share) != null;
+            return ResultData(null, b, b ? "添加成功" : "添加失败");
+        }
+
+        /// <summary>
+        /// 移除快速分享
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult Remove(int id)
+        {
+            bool b = FastShareService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除成功" : "删除失败");
+        }
+
+        /// <summary>
+        /// 更新快速分享
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult Update(FastShare model)
+        {
+            FastShare share = FastShareService.GetById(model.Id);
+            share.Title = model.Title;
+            share.Link = model.Link;
+            share.Sort = model.Sort;
+            bool b = FastShareService.UpdateEntitySaved(share);
+            return ResultData(null, b, b ? "更新成功" : "更新失败");
+        }
+    }
+}

+ 317 - 0
src/Masuit.MyBlogs.Core/Controllers/SubscribeController.cs

@@ -0,0 +1,317 @@
+using Common;
+using EFSecondLevelCache.Core;
+using Hangfire;
+using Masuit.MyBlogs.Core.Extensions;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.Tools.DateTimeExt;
+using Masuit.Tools.Logging;
+using Masuit.Tools.Security;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using Masuit.MyBlogs.Core.Configs;
+using WilderMinds.RssSyndication;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 订阅服务
+    /// </summary>
+    public class SubscribeController : BaseController
+    {
+        /// <summary>
+        /// 邮箱广播
+        /// </summary>
+        public IBroadcastService BroadcastService { get; set; }
+
+        /// <summary>
+        /// 文章
+        /// </summary>
+        public IPostService PostService { get; set; }
+
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// 订阅服务
+        /// </summary>
+        /// <param name="broadcastService"></param>
+        /// <param name="postService"></param>
+        /// <param name="hostingEnvironment"></param>
+        public SubscribeController(IBroadcastService broadcastService, IPostService postService, IHostingEnvironment hostingEnvironment)
+        {
+            BroadcastService = broadcastService;
+            PostService = postService;
+            _hostingEnvironment = hostingEnvironment;
+        }
+
+        /// <summary>
+        /// RSS订阅
+        /// </summary>
+        /// <returns></returns>
+        [Route("rss")]
+        public IActionResult Rss()
+        {
+            var time = DateTime.Now.AddDays(-1);
+            string scheme = Request.Scheme;
+            var host = Request.Host;
+            var posts = PostService.LoadEntitiesNoTracking(p => p.Status == Status.Pended && p.ModifyDate >= time, p => p.ModifyDate, false).Select(p => new Item()
+            {
+                Author = new Author()
+                {
+                    Name = p.Author,
+                    Email = p.Email
+                },
+                Body = p.Content,
+                Categories = new List<string>()
+                {
+                    p.Category.Name
+                },
+                Link = new Uri(scheme + "://" + host + "/" + p.Id),
+                PublishDate = p.ModifyDate,
+                Title = p.Title,
+                Permalink = scheme + "://" + host + "/" + p.Id
+            }).Cacheable().ToList();
+            var feed = new Feed()
+            {
+                Title = CommonHelper.SystemSettings["Title"],
+                Description = CommonHelper.SystemSettings["Description"],
+                Link = new Uri(scheme + "://" + host + "/rss"),
+                Copyright = "(c) 2019"
+            };
+            feed.Items.AddRange(posts.ToArray());
+            var rss = feed.Serialize();
+            return Content(rss);
+        }
+
+        /// <summary>
+        /// 邮箱订阅
+        /// </summary>
+        /// <param name="email"></param>
+        /// <returns></returns>
+        [HttpPost, ValidateAntiForgeryToken]
+        public ActionResult Subscribe(string email)
+        {
+            if (bool.TryParse(CommonHelper.SystemSettings["DisabledEmailBroadcast"], out var disabled) && disabled)
+            {
+                return ResultData(null, false, CommonHelper.SystemSettings["DisabledEmailBroadcastTip"]);
+            }
+            Broadcast entity = BroadcastService.GetFirstEntity(b => b.Email.Equals(email, StringComparison.InvariantCultureIgnoreCase));
+            var guid = Guid.NewGuid();
+            if (entity != null)
+            {
+                if (entity.Status == Status.Subscribed)
+                {
+                    return ResultData(null, false, "您已经订阅过了,无需再重复订阅!");
+                }
+                entity.ValidateCode = guid.ToString();
+                entity.UpdateTime = DateTime.Now;
+                BroadcastService.UpdateEntity(entity);
+            }
+            else
+            {
+                BroadcastService.AddEntity(new Broadcast()
+                {
+                    Email = email,
+                    ValidateCode = guid.ToString(),
+                    Status = Status.Subscribing,
+                    UpdateTime = DateTime.Now
+                });
+            }
+            try
+            {
+                var ts = DateTime.Now.GetTotalMilliseconds();
+                string link = Url.Action("Subscribe", "Subscribe", new
+                {
+                    email,
+                    act = "verify",
+                    validate = guid,
+                    timespan = ts,
+                    hash = (email + "verify" + guid + ts).AESEncrypt(AppConfig.BaiduAK)
+                }, "http");
+                BackgroundJob.Enqueue(() => CommonHelper.SendMail(CommonHelper.SystemSettings["Title"] + "博客订阅:" + Request.Host, System.IO.File.ReadAllText(_hostingEnvironment.WebRootPath + "/template/subscribe.html").Replace("{{link}}", link), email));
+                BroadcastService.SaveChanges();
+                return ResultData(null, message: "订阅成功,请打开您的邮箱确认操作后便可收到订阅更新!");
+            }
+            catch (Exception e)
+            {
+                LogManager.Error(GetType(), e);
+                return ResultData(null, false, "订阅失败,这可能是服务器出现了一点问题,去留言板给站长反馈吧!");
+            }
+        }
+
+        /// <summary>
+        /// 取消订阅
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult Cancel()
+        {
+            return View();
+        }
+
+        /// <summary>
+        /// 取消邮箱订阅
+        /// </summary>
+        /// <param name="email"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public ActionResult Cancel(string email)
+        {
+            Broadcast c = BroadcastService.GetFirstEntity(b => b.Email.Equals(email) && b.Status == Status.Subscribed);
+            if (c != null)
+            {
+                var ts = DateTime.Now.GetTotalMilliseconds();
+                string url = Url.Action("Subscribe", "Subscribe", new
+                {
+                    email,
+                    act = "cancel",
+                    validate = c.ValidateCode,
+                    timespan = ts,
+                    hash = (c.Email + "cancel" + c.ValidateCode + ts).AESEncrypt(AppConfig.BaiduAK)
+                }, Request.Scheme);
+                BackgroundJob.Enqueue(() => CommonHelper.SendMail("取消本站订阅", $"请<a href=\"{url}\">点击这里</a>取消订阅本站更新。", email));
+                return Content("取消订阅的链接已经发送到了您的邮箱,请到您的邮箱内进行取消订阅");
+            }
+            return Content("您输入的邮箱没有订阅本站更新,或者已经取消订阅了");
+        }
+
+        /// <summary>
+        /// 邮箱订阅
+        /// </summary>
+        /// <param name="email"></param>
+        /// <param name="act"></param>
+        /// <param name="validate"></param>
+        /// <param name="timespan"></param>
+        /// <param name="hash"></param>
+        /// <returns></returns>
+        public ActionResult Subscribe(string email, string act, string validate, double timespan, string hash)
+        {
+            var ts = DateTime.Now.GetTotalMilliseconds();
+            if (ts - timespan > 86400000)
+            {
+                return Content("链接已失效");
+            }
+            var hash2 = (email + act + validate + timespan).AESEncrypt(AppConfig.BaiduAK);
+            if (!hash2.Equals(hash))
+            {
+                return Content("操作失败,链接已被非法篡改");
+            }
+            Broadcast entity = BroadcastService.GetFirstEntity(b => b.Email.Equals(email, StringComparison.InvariantCultureIgnoreCase) && b.ValidateCode.Equals(validate));
+            if (entity != null)
+            {
+                switch (act)
+                {
+                    case "verify":
+                        entity.Status = Status.Subscribed;
+                        entity.ValidateCode = Guid.NewGuid().ToString();
+                        entity.UpdateTime = DateTime.Now;
+                        BroadcastService.UpdateEntity(entity);
+                        BroadcastService.SaveChanges();
+                        return Content("订阅成功!");
+                    case "cancel":
+                        entity.Status = Status.Canceled;
+                        entity.UpdateTime = DateTime.Now;
+                        BroadcastService.UpdateEntity(entity);
+                        BroadcastService.SaveChanges();
+                        return Content("取消订阅成功,您将不会再接收到文章更新,如果您以后需要再次接收更新推送,可以到主站点重新进行订阅操作!");
+                    default: return RedirectToAction("Index", "Home");
+                }
+            }
+            return Content("该邮箱账户未使用邮件订阅!");
+        }
+
+
+        #region 管理端
+
+        /// <summary>
+        /// 保存订阅
+        /// </summary>
+        /// <param name="model"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Save(Broadcast model)
+        {
+            model.UpdateTime = DateTime.Now;
+            var entry = BroadcastService.GetFirstEntity(c => c.Email.Equals(model.Email));
+            bool b;
+            if (entry is null)
+            {
+                b = BroadcastService.AddEntitySaved(model) != null;
+            }
+            else
+            {
+                entry.Email = model.Email;
+                entry.SubscribeType = model.SubscribeType;
+                entry.UpdateTime = DateTime.Now;
+                b = BroadcastService.UpdateEntitySaved(entry);
+            }
+            return ResultData(model, b, b ? "更新订阅成功!" : "更新订阅失败!");
+        }
+
+        /// <summary>
+        /// 删除订阅
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Delete(int id)
+        {
+            bool b = BroadcastService.DeleteByIdSaved(id);
+            return ResultData(null, b, b ? "删除订阅成功!" : "删除订阅失败!");
+        }
+
+        /// <summary>
+        /// 改变订阅类型
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Change(int id)
+        {
+            Broadcast cast = BroadcastService.GetById(id);
+            Status status = cast.Status;
+            cast.UpdateTime = DateTime.Now;
+            cast.Status = status == Status.Subscribed ? Status.Subscribing : Status.Subscribed;
+            bool b = BroadcastService.UpdateEntitySaved(cast);
+            return ResultData(null, b, status == Status.Subscribed ? "订阅成功" : "取消订阅成功!");
+        }
+
+        /// <summary>
+        /// 获取订阅
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult Get(int id) => ResultData(BroadcastService.GetById(id));
+
+        /// <summary>
+        /// 订阅分页数据
+        /// </summary>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="search"></param>
+        /// <returns></returns>
+        [Authority]
+        public ActionResult GetPageData(int page = 1, int size = 10, string search = "")
+        {
+            List<Broadcast> list;
+            int total;
+            if (string.IsNullOrEmpty(search))
+            {
+                list = BroadcastService.LoadPageEntitiesFromL2CacheNoTracking(page, size, out total, b => true, b => b.UpdateTime, false).ToList();
+            }
+            else
+            {
+                list = BroadcastService.LoadPageEntitiesFromL2CacheNoTracking(page, size, out total, b => b.Email.Contains(search), b => b.UpdateTime, false).ToList();
+            }
+            var pageCount = Math.Ceiling(total * 1.0 / size).ToInt32();
+            return PageResult(list, pageCount, total);
+        }
+
+        #endregion
+    }
+}

+ 131 - 34
src/Masuit.MyBlogs.WebApp/Controllers/SystemController.cs → src/Masuit.MyBlogs.Core/Controllers/SystemController.cs

@@ -1,15 +1,17 @@
 using Common;
-using IBLL;
-using Masuit.MyBlogs.WebApp.Models.Hangfire;
+using Masuit.MyBlogs.Core.Extensions.Hangfire;
+using Masuit.MyBlogs.Core.Hubs;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
 using Masuit.Tools;
 using Masuit.Tools.Hardware;
 using Masuit.Tools.Logging;
 using Masuit.Tools.Models;
 using Masuit.Tools.NoSQL;
 using Masuit.Tools.Systems;
-using Masuit.Tools.Win32;
-using Models.Entity;
-using Models.Enum;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
 using Newtonsoft.Json;
 using System;
 using System.Collections.Concurrent;
@@ -17,24 +19,42 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
-using System.Threading.Tasks;
-using System.Web.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 系统设置
+    /// </summary>
     public class SystemController : AdminController
     {
-        public ISystemSettingBll SystemSettingBll { get; set; }
+        /// <summary>
+        /// 系统设置
+        /// </summary>
+        public ISystemSettingService SystemSettingService { get; set; }
+
+        /// <summary>
+        /// Redis
+        /// </summary>
         public RedisHelper RedisHelper { get; set; }
-        //public IInterviewBll InterviewBll { get; set; }
-        public SystemController(IUserInfoBll userInfoBll, ISystemSettingBll systemSettingBll, RedisHelper redisHelper)
+
+        /// <summary>
+        /// 系统设置
+        /// </summary>
+        /// <param name="userInfoService"></param>
+        /// <param name="systemSettingService"></param>
+        /// <param name="redisHelper"></param>
+        public SystemController(IUserInfoService userInfoService, ISystemSettingService systemSettingService, RedisHelper redisHelper)
         {
-            UserInfoBll = userInfoBll;
-            SystemSettingBll = systemSettingBll;
+            UserInfoService = userInfoService;
+            SystemSettingService = systemSettingService;
             RedisHelper = redisHelper;
         }
 
-        public async Task<ActionResult> GetBaseInfo()
+        /// <summary>
+        /// 获取硬件基本信息
+        /// </summary>
+        /// <returns></returns>
+        public ActionResult GetBaseInfo()
         {
             List<CpuInfo> cpuInfo = SystemInfo.GetCpuInfo();
             RamInfo ramInfo = SystemInfo.GetRamInfo();
@@ -53,7 +73,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             var span = DateTime.Now - CommonHelper.StartupTime;
             var boot = DateTime.Now - SystemInfo.BootTime();
 
-            return Content(await new
+            return Json(new
             {
                 runningTime = $"{span.Days}天{span.Hours}小时{span.Minutes}分钟",
                 bootTime = $"{boot.Days}天{boot.Hours}小时{boot.Minutes}分钟",
@@ -71,26 +91,62 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     mac,
                     ips
                 }
-            }.ToJsonStringAsync().ConfigureAwait(false), "application/json");
+            });
         }
 
+        /// <summary>
+        /// 获取历史性能计数器
+        /// </summary>
+        /// <returns></returns>
         public ActionResult GetHistoryList()
         {
             return Json(new
             {
-                cpu = CommonHelper.HistoryCpuLoad,
-                mem = CommonHelper.HistoryMemoryUsage,
-                temp = CommonHelper.HistoryCpuTemp,
-                read = CommonHelper.HistoryIORead,
-                write = CommonHelper.HistoryIOWrite,
-                down = CommonHelper.HistoryNetReceive,
-                up = CommonHelper.HistoryNetSend
-            }, JsonRequestBehavior.AllowGet);
+                cpu = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.CpuLoad
+                }),
+                mem = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.MemoryUsage
+                }),
+                temp = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.Temperature
+                }),
+                read = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.DiskRead
+                }),
+                write = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.DiskWrite
+                }),
+                down = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.Download
+                }),
+                up = MyHub.PerformanceCounter.Select(c => new[]
+                {
+                    c.Time,
+                    c.Upload
+                }),
+            });
         }
 
+        /// <summary>
+        /// 获取设置信息
+        /// </summary>
+        /// <returns></returns>
         public ActionResult GetSettings()
         {
-            var list = SystemSettingBll.GetAll().Select(s => new
+            var list = SystemSettingService.GetAll().Select(s => new
             {
                 s.Name,
                 s.Value
@@ -98,14 +154,23 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(list);
         }
 
+        /// <summary>
+        /// 获取设置项
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
         [AllowAnonymous]
         public ActionResult GetSetting(string name)
         {
-            var entity = SystemSettingBll.GetFirstEntity(s => s.Name.Equals(name));
+            var entity = SystemSettingService.GetFirstEntity(s => s.Name.Equals(name));
             return ResultData(entity);
         }
 
-        [ValidateInput(false)]
+        /// <summary>
+        /// 保存设置
+        /// </summary>
+        /// <param name="sets"></param>
+        /// <returns></returns>
         public ActionResult Save(string sets)
         {
             SystemSetting[] settings = JsonConvert.DeserializeObject<List<SystemSetting>>(sets).ToArray();
@@ -123,16 +188,28 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             });
             CommonHelper.DenyAreaIP = dic;
             System.IO.File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "denyareaip.txt"), CommonHelper.DenyAreaIP.ToJsonString(), Encoding.UTF8);
-            bool b = SystemSettingBll.AddOrUpdateSaved(s => s.Name, settings) > 0;
-            return ResultData(null, b, b ? "设置保存成功!" : "设置保存失败!");
-        }
+            foreach (var set in settings)
+            {
+                var entry = SystemSettingService.GetFirstEntity(s => s.Name.Equals(set.Name));
+                if (entry is null)
+                {
+                    SystemSettingService.AddEntity(set);
+                }
+                else
+                {
+                    entry.Value = set.Value;
+                    SystemSettingService.UpdateEntity(entry);
+                }
+            }
 
-        public ActionResult CollectMemory()
-        {
-            double p = Windows.ClearMemory();
-            return ResultData(null, true, "内存整理成功,当前内存使用率:" + p.ToString("N") + "%");
+            var b = SystemSettingService.SaveChanges() > 0;
+            return ResultData(null, b, b ? "设置保存成功!" : "设置保存失败!");
         }
 
+        /// <summary>
+        /// 获取状态
+        /// </summary>
+        /// <returns></returns>
         public ActionResult GetStatus()
         {
             Array array = Enum.GetValues(typeof(Status));
@@ -148,6 +225,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(list);
         }
 
+        /// <summary>
+        /// 邮件测试
+        /// </summary>
+        /// <param name="smtp"></param>
+        /// <param name="user"></param>
+        /// <param name="pwd"></param>
+        /// <param name="port"></param>
+        /// <param name="to"></param>
+        /// <returns></returns>
         public ActionResult MailTest(string smtp, string user, string pwd, int port, string to)
         {
             try
@@ -171,6 +257,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             }
         }
 
+        /// <summary>
+        /// 路径测试
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
         public ActionResult PathTest(string path)
         {
             if (path.Equals("/") || path.Equals("\\") || string.IsNullOrWhiteSpace(path))
@@ -188,6 +279,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 return ResultData(null, false, "路径格式不正确!错误信息:\r\n" + e.Message + "\r\n\r\n详细堆栈跟踪:\r\n" + e.StackTrace);
             }
         }
+
         #region 网站防火墙
 
         /// <summary>
@@ -273,6 +365,10 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null);
         }
 
+        /// <summary>
+        /// 获取拦截日志
+        /// </summary>
+        /// <returns></returns>
         public ActionResult InterceptLog()
         {
             List<IpIntercepter> list = RedisHelper.ListRange<IpIntercepter>("intercept");
@@ -334,6 +430,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             }
             return ResultData(null, false);
         }
+
         #endregion
     }
 }

+ 50 - 26
src/Masuit.MyBlogs.WebApp/Controllers/ToolsController.cs → src/Masuit.MyBlogs.Core/Controllers/ToolsController.cs

@@ -1,46 +1,61 @@
-using System;
+using Masuit.MyBlogs.Core.Configs;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Models;
+using Microsoft.AspNetCore.Mvc;
+using Newtonsoft.Json;
+using Quartz;
+using Quartz.Spi;
+using System;
 using System.Collections.Generic;
-using System.Configuration;
 using System.Linq;
 using System.Net.Http;
 using System.Threading.Tasks;
-using System.Web.Mvc;
-using Masuit.Tools.Models;
-using Masuit.Tools.Net;
+
 #if DEBUG
 using Masuit.Tools.Win32;
 #endif
-using Newtonsoft.Json;
-using Quartz;
-using Quartz.Spi;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
-    [RoutePrefix("tools")]
+    /// <summary>
+    /// 黑科技
+    /// </summary>
+    [Route("tools")]
     public class ToolsController : BaseController
     {
+        /// <summary>
+        /// 获取ip地址详细信息
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <returns></returns>
         [HttpGet, Route("ip/{ip?}")]
         public async Task<ActionResult> GetIpInfo(string ip)
         {
             if (string.IsNullOrEmpty(ip))
             {
-                ip = Request.UserHostAddress;
+                ip = HttpContext.Connection.RemoteIpAddress.ToString();
             }
             ViewBag.IP = ip;
             PhysicsAddress address = await ip.GetPhysicsAddressInfo();
-            if (Request.HttpMethod.ToLower().Equals("get"))
+            if (Request.Method.ToLower().Equals("get"))
             {
                 return View(address);
             }
             return Json(address);
         }
 
+        /// <summary>
+        /// 根据经纬度获取详细地理信息
+        /// </summary>
+        /// <param name="lat"></param>
+        /// <param name="lng"></param>
+        /// <returns></returns>
         [HttpGet, Route("pos")]
         public async Task<ActionResult> Position(string lat, string lng)
         {
             if (string.IsNullOrEmpty(lat) || string.IsNullOrEmpty(lng))
             {
-                var ip = Request.UserHostAddress;
+                var ip = HttpContext.Connection.RemoteIpAddress.ToString();
 #if DEBUG
                 Random r = new Random();
                 ip = $"{r.StrictNext(210)}.{r.StrictNext(255)}.{r.StrictNext(255)}.{r.StrictNext(255)}";
@@ -53,18 +68,23 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 BaseAddress = new Uri("http://api.map.baidu.com")
             })
             {
-                var s = await client.GetStringAsync($"/geocoder/v2/?location={lat},{lng}&output=json&pois=1&ak={ConfigurationManager.AppSettings["BaiduAK"]}");
+                var s = await client.GetStringAsync($"/geocoder/v2/?location={lat},{lng}&output=json&pois=1&ak={AppConfig.BaiduAK}");
                 PhysicsAddress physicsAddress = JsonConvert.DeserializeObject<PhysicsAddress>(s);
                 return View(physicsAddress);
             }
         }
 
+        /// <summary>
+        /// 详细地理信息转经纬度
+        /// </summary>
+        /// <param name="addr"></param>
+        /// <returns></returns>
         [HttpGet, Route("addr")]
         public async Task<ActionResult> Address(string addr)
         {
             if (string.IsNullOrEmpty(addr))
             {
-                var ip = Request.UserHostAddress;
+                var ip = HttpContext.Connection.RemoteIpAddress.ToString();
 #if DEBUG
                 Random r = new Random();
                 ip = $"{r.StrictNext(210)}.{r.StrictNext(255)}.{r.StrictNext(255)}.{r.StrictNext(255)}";
@@ -73,7 +93,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 if (address.Status == 0)
                 {
                     ViewBag.Address = address.AddressResult.FormattedAddress;
-                    if (Request.HttpMethod.ToLower().Equals("get"))
+                    if (Request.Method.ToLower().Equals("get"))
                     {
                         return View(address.AddressResult.Location);
                     }
@@ -86,7 +106,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                 BaseAddress = new Uri("http://api.map.baidu.com")
             })
             {
-                var s = await client.GetStringAsync($"/geocoder/v2/?output=json&address={addr}&ak={ConfigurationManager.AppSettings["BaiduAK"]}");
+                var s = await client.GetStringAsync($"/geocoder/v2/?output=json&address={addr}&ak={AppConfig.BaiduAK}");
                 var physicsAddress = JsonConvert.DeserializeAnonymousType(s, new
                 {
                     status = 0,
@@ -95,7 +115,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                         location = new Location()
                     }
                 });
-                if (Request.HttpMethod.ToLower().Equals("get"))
+                if (Request.Method.ToLower().Equals("get"))
                 {
                     return View(physicsAddress.result.location);
                 }
@@ -103,23 +123,27 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             }
         }
 
-        [Route("vip")]
-        public ActionResult Videos()
-        {
-            return View();
-        }
-
+        /// <summary>
+        /// corn表达式生成
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("cron")]
         public ActionResult Cron()
         {
             return View();
         }
 
-        [HttpPost]
+        /// <summary>
+        /// corn表达式
+        /// </summary>
+        /// <param name="cron"></param>
+        /// <returns></returns>
+        [HttpPost("cron")]
         public ActionResult Cron(string cron)
         {
             //时间表达式
             ITrigger trigger = TriggerBuilder.Create().WithCronSchedule(cron).Build();
-            IList<DateTimeOffset> dates = TriggerUtils.ComputeFireTimes(trigger as IOperableTrigger, null, 5);
+            var dates = TriggerUtils.ComputeFireTimes(trigger as IOperableTrigger, null, 5);
             List<string> list = new List<string>();
             foreach (DateTimeOffset dtf in dates)
             {

+ 69 - 39
src/Masuit.MyBlogs.WebApp/Controllers/UploadController.cs → src/Masuit.MyBlogs.Core/Controllers/UploadController.cs

@@ -1,27 +1,51 @@
 using Common;
 using Hangfire;
-using Masuit.MyBlogs.WebApp.Models;
-using Masuit.MyBlogs.WebApp.Models.UEditor;
+using Masuit.MyBlogs.Core.Common;
+using Masuit.MyBlogs.Core.Extensions.UEditor;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.ViewModel;
 using Masuit.Tools;
+using Masuit.Tools.AspNetCore.Mime;
+using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
+using Masuit.Tools.Core.Net;
 using Masuit.Tools.Html;
 using Masuit.Tools.Logging;
 using Masuit.Tools.Media;
-using Masuit.Tools.Mvc;
-using Masuit.Tools.Net;
-using Models.DTO;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
 using Newtonsoft.Json;
 using System;
 using System.IO;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading;
-using System.Web;
-using System.Web.Mvc;
 
-namespace Masuit.MyBlogs.WebApp.Controllers
+namespace Masuit.MyBlogs.Core.Controllers
 {
+    /// <summary>
+    /// 文件上传
+    /// </summary>
+    [ApiExplorerSettings(IgnoreApi = true)]
     public class UploadController : Controller
     {
+        private readonly IHostingEnvironment _hostingEnvironment;
+
+        /// <summary>
+        /// 文件上传
+        /// </summary>
+        /// <param name="hostingEnvironment"></param>
+        public UploadController(IHostingEnvironment hostingEnvironment)
+        {
+            _hostingEnvironment = hostingEnvironment;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="data"></param>
+        /// <param name="isTrue"></param>
+        /// <param name="message"></param>
+        /// <returns></returns>
         public ActionResult ResultData(object data, bool isTrue = true, string message = "")
         {
             return Content(JsonConvert.SerializeObject(new
@@ -37,21 +61,25 @@ namespace Masuit.MyBlogs.WebApp.Controllers
 
         #region Word上传转码
 
+        /// <summary>
+        /// 上传Word转码
+        /// </summary>
+        /// <returns></returns>
         [HttpPost]
         public ActionResult UploadWord()
         {
-            var files = Request.Files;
+            var files = Request.Form.Files;
             if (files.Count > 0 && files[0] != null)
             {
-                HttpPostedFileBase file = files[0];
+                var file = files[0];
                 string fileName = file.FileName;
-                if (fileName != null && !Regex.IsMatch(Path.GetExtension(fileName), @"doc|docx"))
+                if (fileName != null && !Regex.IsMatch(Path.GetExtension(fileName), "doc|docx"))
                 {
                     return ResultData(null, false, "文件格式不支持,只能上传doc或者docx的文档!");
                 }
                 if (fileName != null)
                 {
-                    string upload = Request.MapPath("/upload");
+                    string upload = _hostingEnvironment.WebRootPath + "/upload";
                     if (!Directory.Exists(upload))
                     {
                         Directory.CreateDirectory(upload);
@@ -59,22 +87,14 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     string resourceName = string.Empty.CreateShortToken(9);
                     string ext = Path.GetExtension(fileName);
                     string docPath = Path.Combine(upload, resourceName + ext);
-                    file.SaveAs(docPath);
+                    using (FileStream fs = new FileStream(docPath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
+                    {
+                        file.CopyTo(fs);
+                    }
                     string htmlDir = docPath.Replace(".docx", "").Replace(".doc", "");
                     DocumentConvert.Doc2Html(docPath, htmlDir);
                     string htmlfile = Path.Combine(htmlDir, "index.html");
                     string html = System.IO.File.ReadAllText(htmlfile).ReplaceHtmlImgSource("/upload/" + resourceName).ClearHtml().HtmlSantinizerStandard();
-                    //MatchCollection matches = Regex.Matches(html, "<img.+?src=\"(.+?)\".+?>");
-                    //foreach (Match m in matches)
-                    //{
-                    //    string src = m.Groups[1].Value;
-                    //    var (url, success) = CommonHelper.UploadImage(Server.MapPath(src));
-                    //    if (success)
-                    //    {
-                    //        html = html.Replace(src, url);
-                    //        BackgroundJob.Enqueue(() => System.IO.File.Delete(Server.MapPath(src)));
-                    //    }
-                    //}
                     ThreadPool.QueueUserWorkItem(state => System.IO.File.Delete(htmlfile));
                     if (html.Length < 10)
                     {
@@ -99,6 +119,11 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             return ResultData(null, false, "请先选择您需要上传的文件!");
         }
 
+        /// <summary>
+        /// 解码Base64图片
+        /// </summary>
+        /// <param name="data"></param>
+        /// <returns></returns>
         public ActionResult DecodeDataUri(string data)
         {
             var dir = "/upload/images";
@@ -106,12 +131,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
             string path = Path.Combine(dir, filename);
             try
             {
-                data.SaveDataUriAsImageFile().Save(Server.MapPath(path), System.Drawing.Imaging.ImageFormat.Jpeg);
+                data.SaveDataUriAsImageFile().Save(_hostingEnvironment.WebRootPath + path, System.Drawing.Imaging.ImageFormat.Jpeg);
                 var (url, success) = CommonHelper.UploadImage(path);
                 BackgroundJob.Enqueue(() => System.IO.File.Delete(path));
                 if (success)
                 {
-                    return ResultData(path);
+                    return ResultData(url);
                 }
                 return ResultData(null, false, "图片上传失败!");
             }
@@ -124,12 +149,17 @@ namespace Masuit.MyBlogs.WebApp.Controllers
 
         #endregion
 
+        /// <summary>
+        /// 文件下载
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
         [Route("download")]
         [Route("download/{path}")]
         public ActionResult Download(string path)
         {
             if (string.IsNullOrEmpty(path)) return Content("null");
-            var file = Path.Combine(Server.MapPath("/upload"), path.Trim('.', '/', '\\'));
+            var file = Path.Combine(_hostingEnvironment.WebRootPath + "/upload", path.Trim('.', '/', '\\'));
             if (System.IO.File.Exists(file))
             {
                 return this.ResumePhysicalFile(file, Path.GetFileName(file));
@@ -144,16 +174,15 @@ namespace Masuit.MyBlogs.WebApp.Controllers
         [Route("fileuploader")]
         public ActionResult UeditorFileUploader()
         {
-            UserInfoOutputDto user = Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
-            var context = System.Web.HttpContext.Current;
-            Handler action = new NotSupportedHandler(context);
-            switch (Request["action"])//通用
+            UserInfoOutputDto user = HttpContext.Session.GetByRedis<UserInfoOutputDto>(SessionKey.UserInfo) ?? new UserInfoOutputDto();
+            Handler action = new NotSupportedHandler(HttpContext);
+            switch (Request.Query["action"])//通用
             {
                 case "config":
-                    action = new ConfigHandler(context);
+                    action = new ConfigHandler(HttpContext);
                     break;
                 case "uploadimage":
-                    action = new UploadHandler(context, new UploadConfig()
+                    action = new UploadHandler(HttpContext, new UploadConfig()
                     {
                         AllowExtensions = UeditorConfig.GetStringList("imageAllowFiles"),
                         PathFormat = UeditorConfig.GetString("imagePathFormat"),
@@ -162,7 +191,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     });
                     break;
                 case "uploadscrawl":
-                    action = new UploadHandler(context, new UploadConfig()
+                    action = new UploadHandler(HttpContext, new UploadConfig()
                     {
                         AllowExtensions = new[] { ".png" },
                         PathFormat = UeditorConfig.GetString("scrawlPathFormat"),
@@ -173,12 +202,12 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     });
                     break;
                 case "catchimage":
-                    action = new CrawlerHandler(context);
+                    action = new CrawlerHandler(HttpContext);
                     break;
             }
             if (user.IsAdmin)
             {
-                switch (Request["action"])//管理员用
+                switch (Request.Query["action"])//管理员用
                 {
                     //case "uploadvideo":
                     //    action = new UploadHandler(context, new UploadConfig()
@@ -190,7 +219,7 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                     //    });
                     //    break;
                     case "uploadfile":
-                        action = new UploadHandler(context, new UploadConfig()
+                        action = new UploadHandler(HttpContext, new UploadConfig()
                         {
                             AllowExtensions = UeditorConfig.GetStringList("fileAllowFiles"),
                             PathFormat = UeditorConfig.GetString("filePathFormat"),
@@ -206,8 +235,9 @@ namespace Masuit.MyBlogs.WebApp.Controllers
                         //    break;
                 }
             }
-            action.Process();
-            return Content("");
+
+            string result = action.Process();
+            return Content(result, ContentType.Json);
         }
     }
 }

+ 87 - 0
src/Masuit.MyBlogs.Core/Controllers/UserController.cs

@@ -0,0 +1,87 @@
+using AutoMapper;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Masuit.MyBlogs.Core.Controllers
+{
+    /// <summary>
+    /// 用户管理
+    /// </summary>
+    public class UserController : AdminController
+    {
+        /// <summary>
+        /// 用户管理
+        /// </summary>
+        /// <param name="userInfoService"></param>
+        public UserController(IUserInfoService userInfoService)
+        {
+            UserInfoService = userInfoService;
+        }
+
+        /// <summary>
+        /// 修改用户名
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="username"></param>
+        /// <returns></returns>
+        public ActionResult ChangeUsername(int id, string username)
+        {
+            UserInfo userInfo = UserInfoService.GetById(id);
+            if (!username.Equals(userInfo.Username) && UserInfoService.UsernameExist(username))
+            {
+                return ResultData(null, false, $"用户名{username}已经存在,请尝试更换其他用户名!");
+            }
+            userInfo.Username = username;
+            bool b = UserInfoService.UpdateEntitySaved(userInfo);
+            return ResultData(Mapper.Map<UserInfoOutputDto>(userInfo), b, b ? $"用户名修改成功,新用户名为{username}。" : "用户名修改失败!");
+        }
+
+        /// <summary>
+        /// 修改昵称
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="username"></param>
+        /// <returns></returns>
+        public ActionResult ChangeNickName(int id, string username)
+        {
+            UserInfo userInfo = UserInfoService.GetById(id);
+            userInfo.NickName = username;
+            bool b = UserInfoService.UpdateEntitySaved(userInfo);
+            return ResultData(Mapper.Map<UserInfoOutputDto>(userInfo), b, b ? $"昵称修改成功,新昵称为{username}。" : "昵称修改失败!");
+        }
+
+        /// <summary>
+        /// 修改密码
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="old"></param>
+        /// <param name="pwd"></param>
+        /// <param name="pwd2"></param>
+        /// <returns></returns>
+        public ActionResult ChangePassword(int id, string old, string pwd, string pwd2)
+        {
+            if (pwd.Equals(pwd2))
+            {
+                bool b = UserInfoService.ChangePassword(id, old, pwd);
+                return ResultData(null, b, b ? $"密码修改成功,新密码为:{pwd}!" : "密码修改失败,可能是原密码不正确!");
+            }
+            return ResultData(null, false, "两次输入的密码不一致!");
+        }
+
+        /// <summary>
+        /// 修改头像
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        public ActionResult ChangeAvatar(int id, string path)
+        {
+            UserInfo userInfo = UserInfoService.GetById(id);
+            userInfo.Avatar = path;
+            bool b = UserInfoService.UpdateEntitySaved(userInfo);
+            return ResultData(Mapper.Map<UserInfoOutputDto>(userInfo), b, b ? $"头像修改成功。" : "头像修改失败!");
+        }
+    }
+}

+ 28 - 23
src/Masuit.MyBlogs.WebApp/Models/AuthorityAttribute.cs → src/Masuit.MyBlogs.Core/Extensions/AuthorityAttribute.cs

@@ -1,26 +1,30 @@
-using System;
-using System.Configuration;
-using System.Text;
+using Masuit.MyBlogs.Core.Configs;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.Security;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using System;
+using System.Linq;
 using System.Web;
-using System.Web.Mvc;
+
 //using Autofac;
-using IBLL;
-using Masuit.Tools.Net;
-using Masuit.Tools.Security;
-using Models.DTO;
 
-namespace Masuit.MyBlogs.WebApp.Models
+namespace Masuit.MyBlogs.Core.Extensions
 {
     public class AuthorityAttribute : ActionFilterAttribute
     {
-        public IUserInfoBll UserInfoBll { get; set; }
+        public IUserInfoService UserInfoService { get; set; }
         /// <summary>在执行操作方法之前由 ASP.NET MVC 框架调用。</summary>
         /// <param name="filterContext">筛选器上下文。</param>
         public override void OnActionExecuting(ActionExecutingContext filterContext)
         {
-            if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Length > 0)
+            if (filterContext.Filters.Any(m => m.ToString().Contains(nameof(AllowAnonymousAttribute))))
             {
-                filterContext.HttpContext.SkipAuthorization = true;
                 return;
             }
 #if !DEBUG
@@ -30,36 +34,37 @@ namespace Masuit.MyBlogs.WebApp.Models
                 //先尝试自动登录
                 if (filterContext.HttpContext.Request.Cookies.Count > 2)
                 {
-                    string name = CookieHelper.GetCookieValue("username");
-                    string pwd = CookieHelper.GetCookieValue("password")?.DesDecrypt(ConfigurationManager.AppSettings["BaiduAK"]);
-                    var userInfo = UserInfoBll.Login(name, pwd);
+                    string name = filterContext.HttpContext.Request.Cookies["username"];
+                    string pwd = filterContext.HttpContext.Request.Cookies["password"]?.DesDecrypt(AppConfig.BaiduAK);
+
+                    var userInfo = UserInfoService.Login(name, pwd);
                     if (userInfo != null)
                     {
-                        CookieHelper.SetCookie("username", name, DateTime.Now.AddDays(7));
-                        CookieHelper.SetCookie("password", CookieHelper.GetCookieValue("password"), DateTime.Now.AddDays(7));
+                        filterContext.HttpContext.Response.Cookies.Append("username", name, new CookieOptions() { Expires = DateTime.Now.AddDays(7) });
+                        filterContext.HttpContext.Response.Cookies.Append("password", pwd, new CookieOptions() { Expires = DateTime.Now.AddDays(7) });
                         filterContext.HttpContext.Session.SetByRedis(SessionKey.UserInfo, userInfo);
                     }
                     else
                     {
-                        if (filterContext.HttpContext.Request.HttpMethod.ToLower().Equals("get"))
+                        if (filterContext.HttpContext.Request.Method.ToLower().Equals("get"))
                         {
-                            filterContext.Result = new RedirectResult("/passport/login?from=" + HttpUtility.UrlEncode(filterContext.HttpContext.Request.Url?.ToString())?.Replace("#", "%23"));
+                            filterContext.Result = new RedirectResult("/passport/login?from=" + HttpUtility.UrlEncode(filterContext.HttpContext.Request.Path.ToString())?.Replace("#", "%23"));
                         }
                         else
                         {
-                            filterContext.Result = new JsonResult { ContentEncoding = Encoding.UTF8, ContentType = "application/json", Data = new { StatusCode = 200, Success = false, IsLogin = false, Message = "未登录系统,请先登录!" }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
+                            filterContext.Result = new JsonResult(new { StatusCode = 200, Success = false, IsLogin = false, Message = "未登录系统,请先登录!" });
                         }
                     }
                 }
                 else
                 {
-                    if (filterContext.HttpContext.Request.HttpMethod.ToLower().Equals("get"))
+                    if (filterContext.HttpContext.Request.Method.ToLower().Equals("get"))
                     {
-                        filterContext.Result = new RedirectResult("/passport/login?from=" + HttpUtility.UrlEncode(filterContext.HttpContext.Request.Url?.ToString()));
+                        filterContext.Result = new RedirectResult("/passport/login?from=" + HttpUtility.UrlEncode(filterContext.HttpContext.Request.Path.ToString()));
                     }
                     else
                     {
-                        filterContext.Result = new JsonResult { ContentEncoding = Encoding.UTF8, ContentType = "application/json", Data = new { StatusCode = 200, Success = false, IsLogin = false, Message = "未登录系统,请先登录!" }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
+                        filterContext.Result = new JsonResult(new { StatusCode = 200, Success = false, IsLogin = false, Message = "未登录系统,请先登录!" });
                     }
                 }
             }

+ 72 - 0
src/Masuit.MyBlogs.Core/Extensions/ExceptionMiddleware.cs

@@ -0,0 +1,72 @@
+using Masuit.Tools.Logging;
+using Microsoft.AspNetCore.Http;
+using Microsoft.EntityFrameworkCore;
+using Newtonsoft.Json;
+using System;
+using System.Threading.Tasks;
+
+namespace Masuit.MyBlogs.Core.Extensions
+{
+    public class ExceptionMiddleware
+    {
+        private readonly RequestDelegate _next;
+        public ExceptionMiddleware(RequestDelegate next)
+        {
+            _next = next;
+        }
+        public async Task Invoke(HttpContext context)
+        {
+            try
+            {
+                await _next.Invoke(context);
+            }
+            catch (DbUpdateConcurrencyException ex)
+            {
+                var err = $"异常源:{ex.Source},异常类型:{ex.GetType().Name},\n请求路径:{context.Request.Scheme}://{context.Request.Host}{context.Request.Path.Value},客户端用户代理:{context.Request.Headers["User-Agent"]},客户端IP:{context.Connection.RemoteIpAddress}\t{ex.InnerException?.Message}\t";
+                LogManager.Error(err, ex);
+                await RedirectError(context);
+            }
+            catch (DbUpdateException ex)
+            {
+                var err = $"异常源:{ex.Source},异常类型:{ex.GetType().Name},\n请求路径:{context.Request.Scheme}://{context.Request.Host}{context.Request.Path.Value},客户端用户代理:{context.Request.Headers["User-Agent"]},客户端IP:{context.Connection.RemoteIpAddress}\t{ex?.InnerException?.Message}\t";
+                LogManager.Error(err, ex);
+                await RedirectError(context);
+            }
+            catch (AggregateException ex)
+            {
+                LogManager.Debug("↓↓↓" + ex.Message + "↓↓↓");
+                ex.Handle(e =>
+                {
+                    LogManager.Error($"异常源:{e.Source},异常类型:{e.GetType().Name},\n请求路径:{context.Request.Scheme}://{context.Request.Host}{context.Request.Path.Value},客户端用户代理:{context.Request.Headers["User-Agent"]},客户端IP:{context.Connection.RemoteIpAddress}\t", e);
+                    return true;
+                });
+                await RedirectError(context);
+            }
+            catch (Exception ex)
+            {
+                //LogManager.Error(ex);
+                LogManager.Error($"异常源:{ex.Source},异常类型:{ex.GetType().Name},\n请求路径:{context.Request.Scheme}://{context.Request.Host}{context.Request.Path.Value},客户端用户代理:{context.Request.Headers["User-Agent"]},客户端IP:{context.Connection.RemoteIpAddress}\t", ex);
+                await RedirectError(context);
+            }
+        }
+
+        private static async Task RedirectError(HttpContext context)
+        {
+            switch (context.Request.Method.ToLower())
+            {
+                case "get":
+                    context.Response.Redirect("/ServiceUnavailable");
+                    break;
+                default:
+                    context.Response.ContentType = "application/json";
+                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new
+                    {
+                        StatusCode = 503,
+                        Success = false,
+                        Message = "服务器发生错误!"
+                    }));
+                    break;
+            }
+        }
+    }
+}

+ 84 - 0
src/Masuit.MyBlogs.Core/Extensions/FirewallMiddleware.cs

@@ -0,0 +1,84 @@
+using Common;
+using Hangfire;
+using Masuit.MyBlogs.Core.Extensions.Hangfire;
+using Masuit.Tools;
+using Masuit.Tools.NoSQL;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Net.Http.Headers;
+using System;
+using System.Threading.Tasks;
+
+namespace Masuit.MyBlogs.Core.Extensions
+{
+    /// <summary>
+    /// 网站防火墙
+    /// </summary>
+    public class FirewallMiddleware
+    {
+        private readonly RequestDelegate _next;
+        private readonly RedisHelper _redisHelper;
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="next"></param>
+        /// <param name="redisHelper"></param>
+        public FirewallMiddleware(RequestDelegate next, RedisHelper redisHelper)
+        {
+            _next = next;
+            _redisHelper = redisHelper;
+        }
+
+        public async Task Invoke(HttpContext context)
+        {
+            context.Response.Headers.Add("Pragma", "no-cache");
+            context.Response.Headers.Add("Expires", "0");
+            context.Response.Headers[HeaderNames.Expires] = "0";
+            context.Response.Headers[HeaderNames.CacheControl] = "no-cache";
+
+            string httpMethod = context.Request.Method;
+            if (httpMethod.Equals("OPTIONS", StringComparison.InvariantCultureIgnoreCase) || httpMethod.Equals("HEAD", StringComparison.InvariantCultureIgnoreCase))
+            {
+                return;
+            }
+
+#if DEBUG
+            if (context.Connection.RemoteIpAddress.ToString().IsDenyIpAddress())
+            {
+                await context.Response.WriteAsync($"检测到您的IP({context.Connection.RemoteIpAddress})异常,已被本站禁止访问,如有疑问,请联系站长!");
+                BackgroundJob.Enqueue(() => HangfireBackJob.InterceptLog(new IpIntercepter()
+                {
+                    IP = context.Connection.RemoteIpAddress.ToString(),
+                    RequestUrl = context.Request.Host.ToString(),
+                    Time = DateTime.Now
+                }));
+                return;
+            }
+#endif
+            bool isSpider = context.Request.Headers[HeaderNames.UserAgent].ToString().Contains(new[]
+            {
+                "DNSPod",
+                "Baidu",
+                "spider",
+                "Python",
+                "bot"
+            });
+            if (isSpider) return;
+            try
+            {
+                var times = _redisHelper.StringIncrement("Frequency:" + context.Connection.Id);
+                _redisHelper.Expire("Frequency:" + context.Connection.Id, TimeSpan.FromMinutes(1));
+                if (times > 300)
+                {
+                    await context.Response.WriteAsync($"检测到您的IP({context.Connection.RemoteIpAddress})访问过于频繁,已被本站暂时禁止访问,如有疑问,请联系站长!");
+                    return;
+                }
+            }
+            catch
+            {
+                // ignored
+            }
+            await _next.Invoke(context);
+        }
+    }
+}

+ 159 - 0
src/Masuit.MyBlogs.Core/Extensions/Hangfire/HangfireBackJob.cs

@@ -0,0 +1,159 @@
+using Common;
+using Masuit.MyBlogs.Core.Infrastructure.Services.Interface;
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+using Masuit.Tools;
+using Masuit.Tools.Core.Net;
+using Masuit.Tools.NoSQL;
+using Masuit.Tools.Systems;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Threading.Tasks;
+
+namespace Masuit.MyBlogs.Core.Extensions.Hangfire
+{
+    public class HangfireBackJob : IHangfireBackJob
+    {
+        private readonly IUserInfoService _userInfoService;
+        private readonly IPostService _postService;
+        private readonly ISystemSettingService _settingService;
+        private readonly ISearchDetailsService _searchDetailsService;
+        private readonly ILinksService _linksService;
+        private readonly RedisHelper _redisHelper;
+        private readonly IHttpClientFactory _httpClientFactory;
+
+        public HangfireBackJob(IUserInfoService userInfoService, IPostService postService, ISystemSettingService settingService, ISearchDetailsService searchDetailsService, ILinksService linksService, RedisHelper redisHelper, IHttpClientFactory httpClientFactory)
+        {
+            _userInfoService = userInfoService;
+            _postService = postService;
+            _settingService = settingService;
+            _searchDetailsService = searchDetailsService;
+            _linksService = linksService;
+            _redisHelper = redisHelper;
+            _httpClientFactory = httpClientFactory;
+        }
+
+        public void LoginRecord(UserInfoOutputDto userInfo, string ip, LoginType type)
+        {
+            var result = ip.GetPhysicsAddressInfo().Result;
+            if (result?.Status == 0)
+            {
+                string addr = result.AddressResult.FormattedAddress;
+                string prov = result.AddressResult.AddressComponent.Province;
+                LoginRecord record = new LoginRecord()
+                {
+                    IP = ip,
+                    LoginTime = DateTime.Now,
+                    LoginType = type,
+                    PhysicAddress = addr,
+                    Province = prov
+                };
+                UserInfo u = _userInfoService.GetByUsername(userInfo.Username);
+                u.LoginRecord.Add(record);
+                _userInfoService.UpdateEntitySaved(u);
+                string content = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "template\\login.html").Replace("{{name}}", u.Username).Replace("{{time}}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("{{ip}}", record.IP).Replace("{{address}}", record.PhysicAddress);
+                CommonHelper.SendMail(_settingService.GetFirstEntity(s => s.Name.Equals("Title")).Value + "账号登录通知", content, _settingService.GetFirstEntity(s => s.Name.Equals("ReceiveEmail")).Value);
+            }
+        }
+
+        public void PublishPost(Post p)
+        {
+            p.Status = Status.Pended;
+            p.PostDate = DateTime.Now;
+            p.ModifyDate = DateTime.Now;
+            Post post = _postService.GetById(p.Id);
+            if (post is null)
+            {
+                _postService.AddEntitySaved(post);
+            }
+            else
+            {
+                post.Status = Status.Pended;
+                post.PostDate = DateTime.Now;
+                post.ModifyDate = DateTime.Now;
+                _postService.UpdateEntitySaved(post);
+            }
+        }
+
+        public void RecordPostVisit(int pid)
+        {
+            Post post = _postService.GetById(pid);
+            var record = post.PostAccessRecord.FirstOrDefault(r => r.AccessTime == DateTime.Today);
+            if (record != null)
+            {
+                record.ClickCount += 1;
+            }
+            else
+            {
+                post.PostAccessRecord.Add(new PostAccessRecord
+                {
+                    ClickCount = 1,
+                    AccessTime = DateTime.Today
+                });
+            }
+
+            _postService.UpdateEntitySaved(post);
+        }
+
+        public static void InterceptLog(IpIntercepter s)
+        {
+            using (RedisHelper redisHelper = RedisHelper.GetInstance())
+            {
+                redisHelper.StringIncrement("interceptCount");
+                redisHelper.ListLeftPush("intercept", s);
+            }
+        }
+
+        /// <summary>
+        /// 每天的任务
+        /// </summary>
+        public void EverydayJob()
+        {
+            CommonHelper.IPErrorTimes.RemoveWhere(kv => kv.Value < 100); //将访客访问出错次数少于100的移开
+            _redisHelper.SetString("ArticleViewToken", SnowFlake.GetInstance().GetUniqueShortId(6)); //更新加密文章的密码
+            _redisHelper.StringIncrement("Interview:RunningDays");
+            DateTime time = DateTime.Now.AddMonths(-1);
+            _searchDetailsService.DeleteEntitySaved(s => s.SearchTime < time);
+        }
+
+        /// <summary>
+        /// 检查友链
+        /// </summary>
+        public void CheckLinks()
+        {
+            var links = _linksService.LoadEntities(l => !l.Except).AsParallel();
+            Parallel.ForEach(links, link =>
+            {
+                Uri uri = new Uri(link.Url);
+                HttpClient client = _httpClientFactory.CreateClient();
+                client.DefaultRequestHeaders.UserAgent.Add(ProductInfoHeaderValue.Parse("Mozilla/5.0"));
+                client.DefaultRequestHeaders.Referrer = new Uri("https://masuit.com");
+                client.Timeout = TimeSpan.FromHours(10);
+                client.GetAsync(uri).ContinueWith(async t =>
+                {
+                    if (t.IsCanceled || t.IsFaulted)
+                    {
+                        link.Status = Status.Unavailable;
+                        return;
+                    }
+                    var res = await t;
+                    if (res.IsSuccessStatusCode)
+                    {
+                        link.Status = !(await res.Content.ReadAsStringAsync()).Contains(CommonHelper.SystemSettings["Domain"]) ? Status.Unavailable : Status.Available;
+                    }
+                    else
+                    {
+                        link.Status = Status.Unavailable;
+                    }
+                    _linksService.UpdateEntity(link);
+                }).Wait();
+            });
+            _linksService.SaveChanges();
+        }
+    }
+}

+ 15 - 0
src/Masuit.MyBlogs.Core/Extensions/Hangfire/IHangfireBackJob.cs

@@ -0,0 +1,15 @@
+using Masuit.MyBlogs.Core.Models.DTO;
+using Masuit.MyBlogs.Core.Models.Entity;
+using Masuit.MyBlogs.Core.Models.Enum;
+
+namespace Masuit.MyBlogs.Core.Extensions.Hangfire
+{
+    public interface IHangfireBackJob
+    {
+        void LoginRecord(UserInfoOutputDto userInfo, string ip, LoginType type);
+        void PublishPost(Post p);
+        void RecordPostVisit(int pid);
+        void EverydayJob();
+        void CheckLinks();
+    }
+}

+ 1 - 1
src/Masuit.MyBlogs.WebApp/Models/Hangfire/IpIntercepter.cs → src/Masuit.MyBlogs.Core/Extensions/Hangfire/IpIntercepter.cs

@@ -1,6 +1,6 @@
 using System;
 
-namespace Masuit.MyBlogs.WebApp.Models.Hangfire
+namespace Masuit.MyBlogs.Core.Extensions.Hangfire
 {
     public class IpIntercepter
     {

+ 16 - 0
src/Masuit.MyBlogs.Core/Extensions/IApplicationBuilderExtensions.cs

@@ -0,0 +1,16 @@
+using Microsoft.AspNetCore.Builder;
+
+namespace Masuit.MyBlogs.Core.Extensions
+{
+    public static class IApplicationBuilderExtensions
+    {
+        public static IApplicationBuilder UseFirewall(this IApplicationBuilder builder)
+        {
+            return builder.UseMiddleware<FirewallMiddleware>();
+        }
+        public static IApplicationBuilder UseException(this IApplicationBuilder builder)
+        {
+            return builder.UseMiddleware<ExceptionMiddleware>();
+        }
+    }
+}

+ 3 - 2
src/Masuit.MyBlogs.WebApp/Models/LuceneHelper.cs → src/Masuit.MyBlogs.Core/Extensions/LuceneHelper.cs

@@ -1,4 +1,5 @@
-using Newtonsoft.Json;
+using Masuit.MyBlogs.Core.Models.ViewModel;
+using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -6,7 +7,7 @@ using System.Net;
 using System.Net.Http;
 using System.Text.RegularExpressions;
 
-namespace Masuit.MyBlogs.WebApp.Models
+namespace Masuit.MyBlogs.Core.Extensions
 {
     /// <summary>
     /// Lucene帮助类

+ 27 - 0
src/Masuit.MyBlogs.Core/Extensions/UEditor/ConfigHandler.cs

@@ -0,0 +1,27 @@
+using Microsoft.AspNetCore.Http;
+
+namespace Masuit.MyBlogs.Core.Extensions.UEditor
+{
+    /// <summary>
+    /// Config 的摘要说明
+    /// </summary>
+    public class ConfigHandler : Handler
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="context"></param>
+        public ConfigHandler(HttpContext context) : base(context)
+        {
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
+        public override string Process()
+        {
+            return WriteJson(UeditorConfig.Items);
+        }
+    }
+}

+ 10 - 12
src/Masuit.MyBlogs.WebApp/Models/UEditor/CrawlerHandler.cs → src/Masuit.MyBlogs.Core/Extensions/UEditor/CrawlerHandler.cs

@@ -1,11 +1,11 @@
 using Masuit.Tools;
+using Microsoft.AspNetCore.Http;
 using System;
 using System.IO;
 using System.Linq;
 using System.Net;
-using System.Web;
 
-namespace Masuit.MyBlogs.WebApp.Models.UEditor
+namespace Masuit.MyBlogs.Core.Extensions.UEditor
 {
     /// <summary>
     /// Crawler 的摘要说明
@@ -19,19 +19,18 @@ namespace Masuit.MyBlogs.WebApp.Models.UEditor
         {
         }
 
-        public override void Process()
+        public override string Process()
         {
-            _sources = Request.Form.GetValues("source[]");
+            _sources = Request.Form["source[]"];
             if (_sources == null || _sources.Length == 0)
             {
-                WriteJson(new
+                return WriteJson(new
                 {
                     state = "参数错误:没有指定抓取源"
                 });
-                return;
             }
-            _crawlers = _sources.Select(x => new Crawler(x, Server).Fetch()).ToArray();
-            WriteJson(new
+            _crawlers = _sources.Select(x => new Crawler(x).Fetch()).ToArray();
+            return WriteJson(new
             {
                 state = "SUCCESS",
                 list = _crawlers.Select(x => new
@@ -50,13 +49,12 @@ namespace Masuit.MyBlogs.WebApp.Models.UEditor
         public string ServerUrl { get; set; }
         public string State { get; set; }
 
-        private HttpServerUtility Server { get; set; }
+        //private HttpServerUtility Server { get; set; }
 
 
-        public Crawler(string sourceUrl, HttpServerUtility server)
+        public Crawler(string sourceUrl)
         {
             SourceUrl = sourceUrl;
-            Server = server;
         }
 
         public Crawler Fetch()
@@ -80,7 +78,7 @@ namespace Masuit.MyBlogs.WebApp.Models.UEditor
                     return this;
                 }
                 ServerUrl = PathFormatter.Format(Path.GetFileName(SourceUrl), UeditorConfig.GetString("catcherPathFormat"));
-                var savePath = Server.MapPath(ServerUrl);
+                var savePath = AppContext.BaseDirectory + "wwwroot" + ServerUrl;
                 if (!Directory.Exists(Path.GetDirectoryName(savePath)))
                 {
                     Directory.CreateDirectory(Path.GetDirectoryName(savePath));

+ 33 - 0
src/Masuit.MyBlogs.Core/Extensions/UEditor/Handler.cs

@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Http;
+using Newtonsoft.Json;
+
+namespace Masuit.MyBlogs.Core.Extensions.UEditor
+{
+    /// <summary>
+    /// Handler 的摘要说明
+    /// </summary>
+    public abstract class Handler
+    {
+        protected Handler(HttpContext context)
+        {
+            this.Request = context.Request;
+            this.Response = context.Response;
+            this.Context = context;
+            //this.Server = context.Server;
+        }
+
+        public abstract string Process();
+
+        protected string WriteJson(object response)
+        {
+            string jsonpCallback = Request.Query["callback"];
+            string json = JsonConvert.SerializeObject(response);
+            return string.IsNullOrWhiteSpace(jsonpCallback) ? json : $"{jsonpCallback}({json});";
+        }
+
+        public HttpRequest Request { get; private set; }
+        public HttpResponse Response { get; private set; }
+        public HttpContext Context { get; private set; }
+        //public HttpServerUtility Server { get; private set; }
+    }
+}

+ 12 - 15
src/Masuit.MyBlogs.WebApp/Models/UEditor/ListFileManager.cs → src/Masuit.MyBlogs.Core/Extensions/UEditor/ListFileManager.cs

@@ -1,10 +1,10 @@
-using System;
+using Microsoft.AspNetCore.Http;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using System.Web;
 
-namespace Masuit.MyBlogs.WebApp.Models.UEditor
+namespace Masuit.MyBlogs.Core.Extensions.UEditor
 {
     /// <summary>
     /// FileManager 的摘要说明
@@ -34,23 +34,22 @@ namespace Masuit.MyBlogs.WebApp.Models.UEditor
             _pathToList = pathToList;
         }
 
-        public override void Process()
+        public override string Process()
         {
             try
             {
-                _start = string.IsNullOrEmpty(Request["start"]) ? 0 : Convert.ToInt32(Request["start"]);
-                _size = string.IsNullOrEmpty(Request["size"]) ? UeditorConfig.GetInt("imageManagerListSize") : Convert.ToInt32(Request["size"]);
+                _start = string.IsNullOrEmpty(Request.Query["start"]) ? 0 : Convert.ToInt32(Request.Query["start"]);
+                _size = string.IsNullOrEmpty(Request.Query["size"]) ? UeditorConfig.GetInt("imageManagerListSize") : Convert.ToInt32(Request.Query["size"]);
             }
             catch (FormatException)
             {
                 _state = ResultState.InvalidParam;
-                WriteResult();
-                return;
+                return WriteResult();
             }
             var buildingList = new List<string>();
             try
             {
-                var localPath = Server.MapPath(_pathToList);
+                var localPath = AppContext.BaseDirectory + "wwwroot" + _pathToList;
                 buildingList.AddRange(Directory.GetFiles(localPath, "*", SearchOption.AllDirectories).Where(x => _searchExtensions.Contains(Path.GetExtension(x).ToLower())).Select(x => _pathToList + x.Substring(localPath.Length).Replace("\\", "/")));
                 _total = buildingList.Count;
                 _fileList = buildingList.OrderBy(x => x).Skip(_start).Take(_size).ToArray();
@@ -67,15 +66,13 @@ namespace Masuit.MyBlogs.WebApp.Models.UEditor
             {
                 _state = ResultState.IOError;
             }
-            finally
-            {
-                WriteResult();
-            }
+            var result = WriteResult();
+            return result;
         }
 
-        private void WriteResult()
+        private string WriteResult()
         {
-            WriteJson(new
+            return WriteJson(new
             {
                 state = GetStateString(),
                 list = _fileList?.Select(x => new

+ 4 - 4
src/Masuit.MyBlogs.WebApp/Models/UEditor/NotSupportedHandler.cs → src/Masuit.MyBlogs.Core/Extensions/UEditor/NotSupportedHandler.cs

@@ -1,6 +1,6 @@
-using System.Web;
+using Microsoft.AspNetCore.Http;
 
-namespace Masuit.MyBlogs.WebApp.Models.UEditor
+namespace Masuit.MyBlogs.Core.Extensions.UEditor
 {
     /// <summary>
     /// NotSupportedHandler 的摘要说明
@@ -11,9 +11,9 @@ namespace Masuit.MyBlogs.WebApp.Models.UEditor
         {
         }
 
-        public override void Process()
+        public override string Process()
         {
-            WriteJson(new
+            return WriteJson(new
             {
                 state = "action 参数为空或者 action 不被支持。"
             });

+ 1 - 1
src/Masuit.MyBlogs.WebApp/Models/UEditor/PathFormatter.cs → src/Masuit.MyBlogs.Core/Extensions/UEditor/PathFormatter.cs

@@ -2,7 +2,7 @@
 using System.IO;
 using System.Text.RegularExpressions;
 
-namespace Masuit.MyBlogs.WebApp.Models.UEditor
+namespace Masuit.MyBlogs.Core.Extensions.UEditor
 {
     /// <summary>
     /// PathFormater 的摘要说明

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä