Преглед на файлове

Merge branch 'develop3.0' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0

liqk преди 4 години
родител
ревизия
8809ced42e
променени са 100 файла, в които са добавени 4464 реда и са изтрити 5936 реда
  1. 264 0
      TEAMModelFunction/.gitignore
  2. 35 0
      TEAMModelFunction/MonitorCosmosDB.cs
  3. 17 0
      TEAMModelFunction/MonitorServicesBus.cs
  4. 8 0
      TEAMModelFunction/Properties/serviceDependencies.json
  5. 9 0
      TEAMModelFunction/Properties/serviceDependencies.local.json
  6. 19 0
      TEAMModelFunction/Startup.cs
  7. 24 0
      TEAMModelFunction/TEAMModelFunction.csproj
  8. 11 0
      TEAMModelFunction/host.json
  9. 1 1
      TEAMModelGrpc/Models/ListPid.cs
  10. 3 3
      TEAMModelGrpc/Services/ClassroomService.cs
  11. 3 3
      TEAMModelGrpc/Services/ClassroomStudentService.cs
  12. 3 3
      TEAMModelGrpc/Services/CourseService.cs
  13. 3 3
      TEAMModelGrpc/Services/HomeWorkService.cs
  14. 3 3
      TEAMModelGrpc/Services/KnowledgeService.cs
  15. 3 3
      TEAMModelGrpc/Services/SyllabusService.cs
  16. 3 3
      TEAMModelGrpc/Services/VolumeService.cs
  17. 7 12
      TEAMModelGrpc/Startup.cs
  18. 1 1
      TEAMModelGrpc/TEAMModelOS.GRPC.xml
  19. 1 0
      TEAMModelOS.SDK/Context/Attributes/Azure/CosmosDBAttribute.cs
  20. 61 0
      TEAMModelOS.SDK/Context/Configuration/Option.cs
  21. 798 0
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs
  22. 245 0
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactory.cs
  23. 20 0
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactoryExtensions.cs
  24. 14 0
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactoryOptions.cs
  25. 18 0
      TEAMModelOS.SDK/DI/AzureCosmos/Inner/AzureCosmosDict.cs
  26. 6 4
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosModelInfo.cs
  27. 6 6
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosDbQuery.cs
  28. 53 0
      TEAMModelOS.SDK/DI/AzureCosmos/Inner/AzureCosmosUtil.cs
  29. 1 1
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/ID.cs
  30. 6 1
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/IdPk.cs
  31. 28 23
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/SQLHelperParametric.cs
  32. 17 0
      TEAMModelOS.SDK/DI/AzureRedis/AzureRedisExtensions.cs
  33. 47 0
      TEAMModelOS.SDK/DI/AzureRedis/AzureRedisFactory.cs
  34. 22 0
      TEAMModelOS.SDK/DI/AzureRedis/AzureRedisFactoryExtensions.cs
  35. 14 0
      TEAMModelOS.SDK/DI/AzureRedis/AzureRedisFactoryOptions.cs
  36. 99 0
      TEAMModelOS.SDK/DI/AzureStorage/AzureStorageBlobExtensions.cs
  37. 350 0
      TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactory.cs
  38. 22 0
      TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactoryExtensions.cs
  39. 14 0
      TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactoryOptions.cs
  40. 516 0
      TEAMModelOS.SDK/DI/AzureStorage/AzureStorageTableExtensions.cs
  41. 114 0
      TEAMModelOS.SDK/DI/DingDing/DingDing.cs
  42. 154 0
      TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeID.cs
  43. 28 0
      TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeIDExtensions.cs
  44. 20 0
      TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeIDOptions.cs
  45. 2 2
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/AzureJsonRequest.cs
  46. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/BaseJosnRequest.cs
  47. 2 1
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/JosnRequest.cs
  48. 6 6
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/PaginationRequest.cs
  49. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/BaseResponse.cs
  50. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/DataJsonResponse.cs
  51. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/EmptyJosnResponse.cs
  52. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorJosnResponse.cs
  53. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorModel.cs
  54. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/JsonRPCResult.cs
  55. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJosnResponse.cs
  56. 2 2
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJsonResult.cs
  57. 2 2
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ResponseBuilder.cs
  58. 1 1
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJosnResponse.cs
  59. 2 2
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJsonResult.cs
  60. 1 1
      TEAMModelOS.SDK/Extension/DataResult/PageToken/AzurePagination.cs
  61. 1 1
      TEAMModelOS.SDK/Extension/DataResult/PageToken/AzureTableToken.cs
  62. 1 1
      TEAMModelOS.SDK/Extension/DataResult/PageToken/Pagination.cs
  63. 2 2
      TEAMModelOS.SDK/Extension/DataResult/RequestData/AzureTokenRequest.cs
  64. 1 1
      TEAMModelOS.SDK/Extension/DataResult/RequestData/BaseRequest.cs
  65. 2 2
      TEAMModelOS.SDK/Extension/DataResult/RequestData/PaginationRequest.cs
  66. 22 0
      TEAMModelOS.SDK/Extension/EnumExtensions.cs
  67. 94 0
      TEAMModelOS.SDK/Extension/HttpContextExtensions.cs
  68. 52 0
      TEAMModelOS.SDK/Extension/JsonExtensions.cs
  69. 13 10
      TEAMModelOS.SDK/Extension/MessagePush/Implements/SendCloudService.cs
  70. 94 0
      TEAMModelOS.SDK/Extension/Utils.cs
  71. 1 1
      TEAMModelOS.SDK/Helper/Security/RSACrypt/RSAUtils.cs
  72. 44 44
      TEAMModelOS.SDK/Module/AzureBlob/Configuration/AzureBlobServiceCollectionExtensions.cs
  73. 38 38
      TEAMModelOS.SDK/Module/AzureBlob/Configuration/BlobClientSingleton.cs
  74. 0 1
      TEAMModelOS.SDK/Module/AzureBlob/Configuration/BlobFileDto.cs
  75. 956 943
      TEAMModelOS.SDK/Module/AzureBlob/Implements/AzureBlobDBRepository.cs
  76. 1 2
      TEAMModelOS.SDK/Module/AzureBlob/Interfaces/IAzureBlobDBRepository.cs
  77. 0 19
      TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/AzureCosmosDBOptions.cs
  78. 0 24
      TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/AzureCosmosDBServiceBuilder.cs
  79. 0 45
      TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/AzureCosmosDBServiceCollectionExtensions.cs
  80. 0 49
      TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/CosmosDBClientSingleton.cs
  81. 0 864
      TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/SQLHelper.cs
  82. 0 851
      TEAMModelOS.SDK/Module/AzureCosmosDB/Implements/AzureCosmosDBRepository.cs
  83. 0 30
      TEAMModelOS.SDK/Module/AzureCosmosDB/Interfaces/IAzureCosmosDBRepository.cs
  84. 0 1252
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/AzureCosmosDBV3Repository.cs
  85. 0 60
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/AzureCosmosDBV3ServiceCollectionExtensions.cs
  86. 0 81
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosDBV3ClientSingleton.cs
  87. 0 18
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosDict.cs
  88. 0 97
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/IAzureCosmosDBV3Repository.cs
  89. 0 139
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/PredicateExtensions.cs
  90. 0 45
      TEAMModelOS.SDK/Module/AzureCosmosDBV3/SystemTextJsonCosmosSerializer.cs
  91. 0 17
      TEAMModelOS.SDK/Module/AzureTable/Configuration/AzureTableOptions.cs
  92. 0 80
      TEAMModelOS.SDK/Module/AzureTable/Configuration/HaBookTableContinuationToken.cs
  93. 0 758
      TEAMModelOS.SDK/Module/AzureTable/Implements/AzureTableDBRepository.cs
  94. 0 41
      TEAMModelOS.SDK/Module/AzureTable/Interfaces/IAzureTableDBRepository.cs
  95. 0 1
      TEAMModelOS.SDK/Module/Cache/CSRedisCacheService.cs
  96. 0 307
      TEAMModelOS.SDK/Module/Cache/RedisCacheService.cs
  97. 22 14
      TEAMModelOS.SDK/TEAMModelOS.SDK.csproj
  98. 1 1
      TEAMModelOS.Service/Models/CommonInfo/Inner/SyllabusNode.cs
  99. 2 2
      TEAMModelOS.Service/Models/CommonInfo/ItemInfo.cs
  100. 0 0
      TEAMModelOS.Service/Models/CommonInfo/Knowledge.cs

+ 264 - 0
TEAMModelFunction/.gitignore

@@ -0,0 +1,264 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Azure Functions localsettings file
+local.settings.json
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc

+ 35 - 0
TEAMModelFunction/MonitorCosmosDB.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Microsoft.Azure.Documents;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Azure.WebJobs.Host;
+using Microsoft.Extensions.Logging;
+
+namespace TEAMModelFunction
+{
+    public class MonitorCosmosDB
+    {
+        private readonly IHttpClientFactory _clientFactory;        
+
+        public MonitorCosmosDB( IHttpClientFactory clientFactory)
+        {
+            _clientFactory = clientFactory;            
+        }
+
+        [FunctionName("School")]
+        public async Task School([CosmosDBTrigger(
+            databaseName: "TEAMModelOS",
+            collectionName: "School",
+            ConnectionStringSetting = "CosmosConnection",
+            LeaseCollectionName = "leases")]IReadOnlyList<Document> input, ILogger log)
+        {           
+                if (input != null && input.Count > 0)
+                {
+                    log.LogInformation("Documents modified " + input.Count);
+                    log.LogInformation("First document Id " + input[0].Id);
+                }           
+        }
+    }
+}

+ 17 - 0
TEAMModelFunction/MonitorServicesBus.cs

@@ -0,0 +1,17 @@
+using System;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Azure.WebJobs.Host;
+using Microsoft.Extensions.Logging;
+
+namespace TEAMModelFunction
+{
+    public static class MonitorServicesBus
+    {
+        [FunctionName("test_queue_activetask")]
+        public static void Run([ServiceBusTrigger("test_queue_activetask", Connection = "ServiceBusConnection")]string myQueueItem, ILogger log)
+        {
+            ///ÖØÊÔ´ÎÊý
+            log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
+        }
+    }
+}

+ 8 - 0
TEAMModelFunction/Properties/serviceDependencies.json

@@ -0,0 +1,8 @@
+{
+  "dependencies": {
+    "storage1": {
+      "type": "storage",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}

+ 9 - 0
TEAMModelFunction/Properties/serviceDependencies.local.json

@@ -0,0 +1,9 @@
+{
+  "dependencies": {
+    "storage1": {
+      "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroup')]/providers/Microsoft.Storage/storageAccounts/teammodelstorage",
+      "type": "storage.azure",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}

+ 19 - 0
TEAMModelFunction/Startup.cs

@@ -0,0 +1,19 @@
+using Microsoft.Azure.Functions.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+
+[assembly: FunctionsStartup(typeof(TEAMModelFunction.Startup))]
+namespace TEAMModelFunction
+{
+    public class Startup : FunctionsStartup
+    {
+        public override void Configure(IFunctionsHostBuilder builder)
+        {
+            builder.Services.AddHttpClient();            
+        }
+    }
+}

+ 24 - 0
TEAMModelFunction/TEAMModelFunction.csproj

@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
+    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="3.0.7" />
+    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="4.1.2" />
+    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Update="host.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Update="local.settings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
+    </None>
+  </ItemGroup>
+</Project>

+ 11 - 0
TEAMModelFunction/host.json

@@ -0,0 +1,11 @@
+{
+    "version": "2.0",
+    "logging": {
+        "applicationInsights": {
+            "samplingExcludedTypes": "Request",
+            "samplingSettings": {
+                "isEnabled": true
+            }
+        }
+    }
+}

+ 1 - 1
TEAMModelGrpc/Models/ListPid.cs

@@ -3,7 +3,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 
 namespace TEAMModelGrpc.Models
 {

+ 3 - 3
TEAMModelGrpc/Services/ClassroomService.cs

@@ -7,16 +7,16 @@ using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelGrpc.Models;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 
 namespace TEAMModelGrpc.Services
 {
     public class ClassroomService : IGrpcService
     {
-        public readonly IAzureCosmosDBV3Repository cosmosrepository;
+        public readonly AzureCosmosFactory cosmosrepository;
 
-        public ClassroomService(IAzureCosmosDBV3Repository cosmosrepository)
+        public ClassroomService(AzureCosmosFactory cosmosrepository)
         {
             this.cosmosrepository = cosmosrepository;
         }

+ 3 - 3
TEAMModelGrpc/Services/ClassroomStudentService.cs

@@ -7,15 +7,15 @@ using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelGrpc.Models;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 
 namespace TEAMModelGrpc.Services
 {
     public class ClassStudentService : IGrpcService
     {
-        private IAzureCosmosDBV3Repository _cosmos;
-        public ClassStudentService(IAzureCosmosDBV3Repository cosmos)
+        private AzureCosmosFactory _cosmos;
+        public ClassStudentService(AzureCosmosFactory cosmos)
         {
             _cosmos = cosmos;
         }

+ 3 - 3
TEAMModelGrpc/Services/CourseService.cs

@@ -6,16 +6,16 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelGrpc.Models;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 
 namespace TEAMModelGrpc.Services
 {
     public class CourseService : IGrpcService
     {
-        public IAzureCosmosDBV3Repository _cosmos;
+        public AzureCosmosFactory _cosmos;
 
-        public CourseService(IAzureCosmosDBV3Repository cosmosDBV3Repository)
+        public CourseService(AzureCosmosFactory cosmosDBV3Repository)
         {
             this._cosmos = cosmosDBV3Repository;
         }

+ 3 - 3
TEAMModelGrpc/Services/HomeWorkService.cs

@@ -9,16 +9,16 @@ using TEAMModelOS;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK.Context.Exception;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 
 namespace TEAMModelGrpc.Services
 {
     public class HomeWorkService : IGrpcService
     {
-        private readonly IAzureCosmosDBV3Repository _cosmos;
+        private readonly AzureCosmosFactory _cosmos;
 
-        public HomeWorkService(IAzureCosmosDBV3Repository cosmos)
+        public HomeWorkService(AzureCosmosFactory cosmos)
         {
             _cosmos = cosmos;
         }

+ 3 - 3
TEAMModelGrpc/Services/KnowledgeService.cs

@@ -9,7 +9,7 @@ using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelGrpc.Models;
 using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 using TEAMModelOS.Service.Services.Interface;
 
@@ -18,10 +18,10 @@ namespace TEAMModelGrpc.Services
  
     public class KnowledgeService : IGrpcService
     {
-        private IAzureCosmosDBV3Repository cosmosDBV3Repository;
+        private AzureCosmosFactory cosmosDBV3Repository;
         private IKnowledgeService knowledgeService;
 
-        public KnowledgeService(IAzureCosmosDBV3Repository cosmosDBV3Repository, IKnowledgeService knowledgeService)
+        public KnowledgeService(AzureCosmosFactory cosmosDBV3Repository, IKnowledgeService knowledgeService)
         {
             this.cosmosDBV3Repository = cosmosDBV3Repository;
             this.knowledgeService = knowledgeService;

+ 3 - 3
TEAMModelGrpc/Services/SyllabusService.cs

@@ -7,7 +7,7 @@ using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelGrpc.Models;
 using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 using TEAMModelOS.Service.Services.Interface;
 
@@ -19,13 +19,13 @@ namespace TEAMModelGrpc.Services
     public class SyllabusService : IGrpcService
     {
         private ISyllabusService syllabusService;
-        private IAzureCosmosDBV3Repository cosmosDBV3Repository;
+        private AzureCosmosFactory cosmosDBV3Repository;
         /// <summary>
         /// 构造函数
         /// </summary>
         /// <param name="syllabusService"></param>
         /// <param name="cosmosDBV3Repository"></param>
-        public SyllabusService(ISyllabusService syllabusService, IAzureCosmosDBV3Repository cosmosDBV3Repository)
+        public SyllabusService(ISyllabusService syllabusService, AzureCosmosFactory cosmosDBV3Repository)
         {
             this.syllabusService = syllabusService;
             this.cosmosDBV3Repository = cosmosDBV3Repository;

+ 3 - 3
TEAMModelGrpc/Services/VolumeService.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelGrpc.Models;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 using TEAMModelOS.Service.Models;
 using TEAMModelOS.Service.Services.Interface;
 
@@ -14,10 +14,10 @@ namespace TEAMModelGrpc.Services
 {
     public class VolumeService :IGrpcService
     {
-        private readonly IAzureCosmosDBV3Repository azureCosmosDBRepository;
+        private readonly AzureCosmosFactory azureCosmosDBRepository;
         private IVolumeService volumeService;
 
-        public VolumeService(IAzureCosmosDBV3Repository azureCosmosDBRepository, IVolumeService volumeService)
+        public VolumeService(AzureCosmosFactory azureCosmosDBRepository, IVolumeService volumeService)
         {
             this.azureCosmosDBRepository = azureCosmosDBRepository;
             this.volumeService = volumeService;

+ 7 - 12
TEAMModelGrpc/Startup.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.IdentityModel.Tokens.Jwt;
 using System.Linq;
@@ -17,12 +17,7 @@ using Microsoft.Extensions.Primitives;
 using Microsoft.IdentityModel.Tokens;
 using TEAMModelGrpc.Services;
 using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.SDK.Extension.JwtAuth;
-using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
-using TEAMModelOS.SDK.Module.AzureTable.Implements;
-using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using TEAMModelOS.SDK.DI;
 using Microsoft.Extensions.Diagnostics.HealthChecks;
 
 namespace TEAMModelGrpc
@@ -76,12 +71,12 @@ namespace TEAMModelGrpc
                 });
 
             // Table配置
-            services.AddScoped<IAzureTableDBRepository, AzureTableDBRepository>();
+            //services.AddScoped<IAzureTableDBRepository, AzureTableDBRepository>();
             //使用Blob配置
-            services.AddAzureBlobStorage().AddConnection(_conf.GetSection("Azure:Blob").Get<AzureBlobOptions>());
+            //services.AddAzureBlobStorage().AddConnection(_conf.GetSection("Azure:Blob").Get<AzureBlobOptions>());
             //使用CosmosDB
-            services.AddAzureCosmosDBV3().AddCosmosDBV3Connection(_conf.GetSection("Azure:CosmosDB").Get<AzureCosmosDBOptions>())
-                .AddCosmosSerializer(new SystemTextJsonCosmosSerializer(new JsonSerializerOptions() { IgnoreNullValues = true }));
+            //services.AddAzureCosmosDBV3().AddCosmosDBV3Connection(_conf.GetSection("Azure:CosmosDB").Get<AzureCosmosDBOptions>())
+            //    .AddCosmosSerializer(new SystemTextJsonCosmosSerializer(new JsonSerializerOptions() { IgnoreNullValues = true }));
  
             //注入CSRedis
             var csredis = new CSRedis.CSRedisClient(_conf.GetSection("Azure:Redis:ConnectionString").Get<string>());
@@ -96,7 +91,7 @@ namespace TEAMModelGrpc
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAzureCosmosDBV3Repository cosmosDBV3Repository)
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AzureCosmosFactory cosmosDBV3Repository)
         {
             if (env.IsDevelopment())
             {

+ 1 - 1
TEAMModelGrpc/TEAMModelOS.GRPC.xml

@@ -348,7 +348,7 @@
             课纲业务
             </summary>
         </member>
-        <member name="M:TEAMModelGrpc.Services.SyllabusService.#ctor(TEAMModelOS.Service.Services.Interface.ISyllabusService,TEAMModelOS.SDK.Module.AzureCosmosDBV3.IAzureCosmosDBV3Repository)">
+        <member name="M:TEAMModelGrpc.Services.SyllabusService.#ctor(TEAMModelOS.Service.Services.Interface.ISyllabusService,TEAMModelOS.SDK.DI.AzureCosmosFactory)">
             <summary>
             构造函数
             </summary>

+ 1 - 0
TEAMModelOS.SDK/Context/Attributes/Azure/CosmosDBAttribute.cs

@@ -11,5 +11,6 @@ namespace TEAMModelOS.SDK.Context.Attributes.Azure
         public string Name { get; set; }
         public bool Cache { get; set; } = false;
         public bool Monitor { get; set; } = false;
+        public string Database { get; set; } = "TEAMModelOS";
     }
 }

+ 61 - 0
TEAMModelOS.SDK/Context/Configuration/Option.cs

@@ -0,0 +1,61 @@
+using Microsoft.AspNetCore.Authentication.OAuth;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Primitives;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Models
+{
+    public class Option
+    {
+        public Option()
+        {
+        }
+
+        public string Location { get; set; }
+        public string LocationNum { get; set; }  
+        public string BlobDomain { get; set; }
+        public string HostName { get; set; }
+        public IList<string> AllowedHosts { get; }
+        public IList<StringSegment> AllowedRedirects
+        {
+            get
+            {
+                var allowedRedirects = new List<StringSegment>();
+                if (AllowedHosts?.Count > 0 && !TryProcessHosts(AllowedHosts, allowedRedirects))
+                {
+                    return allowedRedirects;
+                }
+                return allowedRedirects;
+            }
+        }
+        public string JwtSecretKey { get; set; }
+        public string Authority { get; set; }
+        public string Audience { get; set; }
+        public string OSFunction { get; set; }
+
+
+
+        private bool TryProcessHosts(IEnumerable<string> incoming, IList<StringSegment> results)
+        {
+            foreach (var entry in incoming)
+            {
+                // Punycode. Http.Sys requires you to register Unicode hosts, but the headers contain punycode.
+                var host = new HostString(entry).ToUriComponent();
+                if (IsTopLevelWildcard(host)) continue;
+                if (!results.Contains(host, StringSegmentComparer.OrdinalIgnoreCase)) results.Add(host);
+            }
+            return true;
+        }
+
+        private bool IsTopLevelWildcard(string host)
+        {
+            return (string.Equals("*", host, StringComparison.Ordinal) // HttpSys wildcard
+                           || string.Equals("[::]", host, StringComparison.Ordinal) // Kestrel wildcard, IPv6 Any
+                           || string.Equals("0.0.0.0", host, StringComparison.Ordinal)); // IPv4 Any
+        }
+
+    }  
+}

+ 798 - 0
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs

@@ -0,0 +1,798 @@
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Azure.Cosmos.Table.Queryable;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Linq;
+using Azure;
+using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
+using System.IO;
+using TEAMModelOS.SDK.DI;
+using System.Diagnostics;
+using Azure.Cosmos;
+using System.Text.Json;
+using System.Net;
+using TEAMModelOS.SDK.Context.Exception;
+using System.Linq.Expressions;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.Helper.Common.LogHelper;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureCosmosExtensions
+    {
+        /// <summary>
+        /// 遣湔袟
+        /// </summary>
+        private const string CacheCosmosPrefix = "cosmos:";
+        /// <summary>
+        /// ttl奀酗 1鏃
+        /// </summary>
+        private const int ttl = 1;
+        /// <summary>
+        /// 煦珜湮苤
+        /// </summary>
+        private const int pageSize = 200;
+        /// <summary>
+        /// 閉奀奀潔
+        /// </summary>
+        private const int timeoutSeconds = 86400;
+        public static int RU(this Response response)
+        {
+            try
+            {
+                response.Headers.TryGetValue("x-ms-request-charge", out var value);
+                var ru = Convert.ToInt32(value);
+                return ru;
+            }
+            catch (Exception)
+            {
+                return 0;
+            }
+        }
+        public static async Task<T> FindByIdPk<T>(this AzureCosmosFactory azureCosmosFactory, string id, string pk) where T : ID
+        {
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            ItemResponse<T> response = await container.container.ReadItemAsync<T>(id: id, partitionKey: new PartitionKey(pk));
+            return response.Value;
+        }
+        public static async Task<List<T>> FindByIds<T>(this AzureCosmosFactory azureCosmosFactory, List<string> ids) where T : ID
+        {
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            if (container.cache && RedisHelper.Instance != null)
+            {
+                List<T> list = new List<T>();
+                List<string> NotIn = new List<string>();
+                foreach (string id in ids)
+                {
+                    if (!await RedisHelper.HExistsAsync(CacheCosmosPrefix + container.container.Id, id))
+                    {
+                        NotIn.Add(id);
+                    }
+                    else
+                    {
+                        list.Add(await RedisHelper.HGetAsync<T>(CacheCosmosPrefix + container.container.Id, id));
+                    }
+                }
+                if (NotIn.IsNotEmpty())
+                {
+                    List<T> noInList = await FindByDict<T>(azureCosmosFactory, new Dictionary<string, object> { { "id", NotIn.ToArray() } });
+                    noInList.ForEach(x => { RedisHelper.HSet(CacheCosmosPrefix + container.container.Id, x.id, x); RedisHelper.Expire(CacheCosmosPrefix + container.container.Id, timeoutSeconds); });
+                    list.AddRange(noInList);
+                }
+                return list;
+            }
+            else
+            {
+                return await FindByDict<T>(azureCosmosFactory, new Dictionary<string, object> { { "id", ids.ToArray() } });
+            }
+        }
+        public static async Task<T> Save<T>(this AzureCosmosFactory azureCosmosFactory, T entity) where T : ID
+        {
+             
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            entity.pk = container.type.Name;
+            entity.ttl = null;
+            ItemResponse<T> response = await container.container.CreateItemAsync<T>(entity);
+            if (container.cache && RedisHelper.Instance != null)
+            {
+                if (!RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+                {
+                    await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, entity.id, entity);
+                }
+                else
+                {
+                    await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, entity.id, entity);
+                    await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+                }
+            }
+            return response.Value;
+        }
+
+        public static async Task<List<T>> SaveAll<T>(this AzureCosmosFactory azureCosmosFactory, List<T> enyites) where T : ID
+        {
+            int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            bool flag = false;
+            if (RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+            {
+                flag = true;
+            }
+            string partitionKey =AzureCosmosUtil.GetPartitionKey<T>();
+            Type type = typeof(T);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            for (int i = 0; i < pages; i++)
+            {
+                List<T> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
+                List<KeyValuePair<PartitionKey, Stream>> itemsToInsert = new List<KeyValuePair<PartitionKey, Stream>>();
+                lists.ForEach(async x =>
+                {
+                    x.pk = type.Name;
+                    x.ttl = null;
+                    MemoryStream stream = new MemoryStream();
+                    await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
+                    object o = type.GetProperty(partitionKey).GetValue(x, null);
+                    KeyValuePair<PartitionKey, Stream> keyValue = new KeyValuePair<PartitionKey, Stream>(new PartitionKey(o.ToString()), stream);
+                    itemsToInsert.Add(keyValue);
+                });
+                List<Task> tasks = new List<Task>(lists.Count);
+                itemsToInsert.ForEach(item =>
+                {
+                    tasks.Add(container.container.CreateItemStreamAsync(item.Value, item.Key)
+                        .ContinueWith((Task<Response> task) =>
+                        {
+                            using (Response response = task.Result)
+                            {
+                                //if (!response.IsSuccessStatusCode)
+                                //{
+                                //}
+                            }
+                        }
+                        ));
+                });
+                await Task.WhenAll(tasks);
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    lists.ForEach(async x => {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, x.id, x);
+                    });
+                }
+            }
+            if (container.cache && RedisHelper.Instance != null && !flag)
+            {
+                await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+            }
+            stopwatch.Stop();
+            return enyites;
+        }
+        public static async Task<T> SaveOrUpdate<T>(this AzureCosmosFactory azureCosmosFactory, T entity) where T : ID
+        {
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            entity.pk = container.type.Name;
+            entity.ttl = null;
+            ItemResponse<T> response = await container.container.UpsertItemAsync(item: entity);
+            if (container.cache && RedisHelper.Instance != null)
+            {
+                if (!RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+                {
+                    await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, entity.id, entity);
+                }
+                else
+                {
+                    await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, entity.id, entity);
+                    await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+                }
+            }
+            return response.Value;
+        }
+        public static async Task<List<T>> SaveOrUpdateAll<T>(this AzureCosmosFactory azureCosmosFactory, List<T> enyites) where T : ID
+        {
+            int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            bool flag = false;
+            if (RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+            {
+                flag = true;
+            }
+            string partitionKey =AzureCosmosUtil.GetPartitionKey<T>();
+            Type type = typeof(T);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            for (int i = 0; i < pages; i++)
+            {
+                List<T> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
+                List<KeyValuePair<PartitionKey, Stream>> itemsToInsert = new List<KeyValuePair<PartitionKey, Stream>>();
+                lists.ForEach(async x =>
+                {
+                    x.pk = type.Name;
+                    x.ttl = null;
+                    MemoryStream stream = new MemoryStream();
+                    await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
+                    object o = type.GetProperty(partitionKey).GetValue(x, null);
+                    KeyValuePair<PartitionKey, Stream> keyValue = new KeyValuePair<PartitionKey, Stream>(new PartitionKey(o.ToString()), stream);
+                    itemsToInsert.Add(keyValue);
+                });
+                List<Task> tasks = new List<Task>(lists.Count);
+                itemsToInsert.ForEach(item =>
+                {
+                    tasks.Add(container.container.UpsertItemStreamAsync(item.Value, item.Key)
+                        .ContinueWith((Task<Response> task) =>
+                        {
+                        }
+                        ));
+                });
+                await Task.WhenAll(tasks);
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    lists.ForEach(async x => {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, x.id, x);
+                    });
+                }
+            }
+            if (container.cache && RedisHelper.Instance != null && !flag)
+            {
+                await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+            }
+            stopwatch.Stop();
+            return enyites;
+        }
+        public static async Task<List<dynamic>> UpdateAll(this AzureCosmosFactory azureCosmosFactory,  string typeName, List<dynamic> enyites)
+        {
+            int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
+            if (azureCosmosFactory. CosmosDict.typeCosmos.TryGetValue(typeName, out AzureCosmosModel container))
+            {
+            }
+            bool flag = false;
+            if (RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+            {
+                flag = true;
+            }
+            string partitionKey = container.partitionKey;
+
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            for (int i = 0; i < pages; i++)
+            {
+                List<dynamic> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
+                List<Item> itemsToInsert = new List<Item>();
+                lists.ForEach(async x =>
+                {
+                    /* x.pk = typeName;
+                     x.ttl = null;*/
+                    MemoryStream stream = new MemoryStream();
+                    await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
+                    object o = x[partitionKey];
+                    Item keyValue = new Item { id = x.id, pk = o.ToString(), stream = stream };
+                    itemsToInsert.Add(keyValue);
+                });
+                List<Task> tasks = new List<Task>(lists.Count);
+                itemsToInsert.ForEach(item =>
+                {
+                    tasks.Add(container.container.ReplaceItemStreamAsync(item.stream, item.id, new PartitionKey(item.pk))
+                        .ContinueWith((Task<Response> task) =>
+                        {
+                            //using (ResponseMessage response = task.Result)
+                            //{
+                            //    if (!response.IsSuccessStatusCode)
+                            //    {
+                            //    }
+                            //}
+                        }
+                        ));
+                });
+                await Task.WhenAll(tasks);
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    lists.ForEach(async x => {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, x.id, x);
+                    });
+                }
+            }
+            if (container.cache && RedisHelper.Instance != null && !flag)
+            {
+                await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+            }
+            stopwatch.Stop();
+            return enyites;
+        }
+        public static async Task<List<int>> FindCountByDict<T>(this AzureCosmosFactory azureCosmosFactory, Dictionary<string, object> dict)
+        {
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            string pk = typeof(T).Name;
+            StringBuilder sql = new StringBuilder("select  value count(c)  from c");
+            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql, pk);
+            if (cosmosDbQuery == null)
+            {
+                return new List<int> { 0 };
+            }
+            QueryRequestOptions queryRequestOptions = GetDefaultQueryRequestOptions(itemsPerPage: GetEffectivePageSize(-1, null));
+            AsyncPageable<int> query = container.container.GetItemQueryIterator<int>(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: queryRequestOptions);
+            return await ResultsFromFeedIterator(query);
+        }
+
+        public static async Task<List<dynamic>> FindCountByDict(this AzureCosmosFactory azureCosmosFactory, string CollectionName, Dictionary<string, object> dict)
+        {
+            if (azureCosmosFactory.CosmosDict.typeCosmos.TryGetValue(CollectionName, out AzureCosmosModel container))
+            {
+                string pk = container.type.Name;
+                dict.Remove("@CURRPAGE");
+                dict.Remove("@PAGESIZE");
+                dict.Remove("@ASC");
+                dict.Remove("@DESC");
+                StringBuilder sql = new StringBuilder("select  value count(c)  from c");
+                AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql, pk);
+                if (cosmosDbQuery == null)
+                {
+                    return new List<dynamic> { 0 };
+                }
+                QueryRequestOptions queryRequestOptions = GetDefaultQueryRequestOptions(itemsPerPage: GetEffectivePageSize(-1, null));
+                AsyncPageable<dynamic> query = container.container.GetItemQueryIterator<dynamic>(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: queryRequestOptions);
+                return await ResultsFromFeedIterator(query);
+            }
+            else
+            {
+                throw new BizException("CollectionName named:" + CollectionName + " dose not exsit in Database!");
+            }
+        }
+
+        public static async Task<T> Update<T>(this AzureCosmosFactory azureCosmosFactory,  T entity) where T : ID
+        {
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            string partitionKey =AzureCosmosUtil.GetPartitionKey<T>();
+            Type type = typeof(T);
+            entity.pk = type.Name;
+            entity.ttl = null;
+            object o = type.GetProperty(partitionKey).GetValue(entity, null);
+            ItemResponse<T> response = await container.container.ReplaceItemAsync(entity, entity.id, new PartitionKey(o.ToString()));
+            if (container.cache && RedisHelper.Instance != null)
+            {
+                if (!RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+                {
+                    await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, entity.id, entity);
+                }
+                else
+                {
+                    await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, entity.id, entity);
+                    await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+                }
+            }
+            return response.Value;
+        }
+        internal class Item
+        {
+            public string id { get; set; }
+            public string pk { get; set; }
+            public MemoryStream stream { get; set; }
+        }
+        public static async Task<List<T>> UpdateAll<T>(this AzureCosmosFactory azureCosmosFactory,  List<T> enyites) where T : ID
+        {
+            //await Task.Run(() => Parallel.ForEach(entities, new ParallelOptions { MaxDegreeOfParallelism = 2 }, (item) =>
+            //{
+            //    Task.WaitAll(Update(item));
+            //}));
+
+            int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            bool flag = false;
+            if (RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+            {
+                flag = true;
+            }
+            string partitionKey =AzureCosmosUtil.GetPartitionKey<T>();
+            Type type = typeof(T);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            for (int i = 0; i < pages; i++)
+            {
+                List<T> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
+                List<Item> itemsToInsert = new List<Item>();
+                lists.ForEach(async x =>
+                {
+                    x.pk = type.Name;
+                    x.ttl = null;
+                    MemoryStream stream = new MemoryStream();
+                    await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
+                    object o = type.GetProperty(partitionKey).GetValue(x, null);
+                    Item keyValue = new Item { id = x.id, pk = o.ToString(), stream = stream };
+                    itemsToInsert.Add(keyValue);
+                });
+                List<Task> tasks = new List<Task>(lists.Count);
+                itemsToInsert.ForEach(item =>
+                {
+                    tasks.Add(container.container.ReplaceItemStreamAsync(item.stream, item.id, new PartitionKey(item.pk))
+                        .ContinueWith((Task<Response> task) =>
+                        {
+                            //using (ResponseMessage response = task.Result)
+                            //{
+                            //    if (!response.IsSuccessStatusCode)
+                            //    {
+                            //    }
+                            //}
+                        }
+                        ));
+                });
+                await Task.WhenAll(tasks);
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    lists.ForEach(async x => {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, x.id, x);
+                    });
+                }
+            }
+            if (container.cache && RedisHelper.Instance != null && !flag)
+            {
+                await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+            }
+            stopwatch.Stop();
+            return enyites;
+        }
+
+
+        public static async Task<List<T>> FindByDict<T>(this AzureCosmosFactory azureCosmosFactory, Dictionary<string, object> dict, List<string> propertys = null) where T : ID
+        {
+            StringBuilder sql;
+            sql = SQLHelper.GetSQLSelect(propertys);
+            string pk = typeof(T).Name;
+            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql, pk);
+            QueryRequestOptions queryRequestOptions = GetDefaultQueryRequestOptions(itemsPerPage: GetEffectivePageSize(-1, null));
+            return await ResultsFromQueryAndOptions<T>(azureCosmosFactory,cosmosDbQuery, queryRequestOptions);
+        }
+
+
+        public static async Task<List<dynamic>> FindByDict(this AzureCosmosFactory azureCosmosFactory, string CollectionName, Dictionary<string, object> dict, List<string> propertys = null)
+        {
+            if (azureCosmosFactory.CosmosDict.typeCosmos.TryGetValue(CollectionName, out AzureCosmosModel container))
+            {
+
+                string pk = container.type.Name;
+                StringBuilder sql;
+                sql = SQLHelper.GetSQLSelect(propertys);
+                AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql, pk);
+                QueryRequestOptions queryRequestOptions = GetDefaultQueryRequestOptions(itemsPerPage: GetEffectivePageSize(-1, null));
+                AsyncPageable<dynamic> query = container.container.GetItemQueryIterator<dynamic>(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: queryRequestOptions);
+                return await ResultsFromFeedIterator(query);
+            }
+            else
+            {
+                throw new BizException("CollectionName named:" + CollectionName + " dose not exsit in Database!");
+            }
+        }
+        public static async Task<List<IdPk>> DeleteAll<T>(this AzureCosmosFactory azureCosmosFactory, List<IdPk> ids) where T : ID
+        {
+
+            //   string pk = GetPartitionKey<T>();
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            List<IdPk> idPks = new List<IdPk>();
+            if (container.monitor)
+            {
+                List<T> list = await azureCosmosFactory.FindByDict<T>(new Dictionary<string, object>() { { "id", ids.Select(x => x.id).ToArray() } });
+                list = await azureCosmosFactory. DeleteTTL(list);
+                return ids;
+            }
+            else
+            {
+                int pages = (int)Math.Ceiling((double)ids.Count / pageSize);
+                Stopwatch stopwatch = Stopwatch.StartNew();
+                for (int i = 0; i < pages; i++)
+                {
+                    List<IdPk> lists = ids.Skip((i) * pageSize).Take(pageSize).ToList();
+                    List<Task> tasks = new List<Task>(lists.Count);
+                    lists.ForEach(item =>
+                    {
+                        tasks.Add(container.container.DeleteItemStreamAsync(item.id, new PartitionKey(item.pk))
+                            .ContinueWith((Task<Response> task) =>
+                            {
+                                using (Response response = task.Result)
+                                {
+                                    idPks.Add(new IdPk { id = item.id, pk = item.pk, Status = response.Status });
+                                    //    if (!response.IsSuccessStatusCode)
+                                    //    {
+                                    //    }
+                                }
+                            }
+                            ));
+                    });
+                    await Task.WhenAll(tasks);
+                    if (container.cache && RedisHelper.Instance != null)
+                    {
+                        lists.ForEach(async x => {
+                            await RedisHelper.HDelAsync(CacheCosmosPrefix + container.container.Id, x.id);
+                        });
+                    }
+                }
+                stopwatch.Stop();
+                return idPks;
+            }
+        }
+        public static async Task<List<IdPk>> DeleteAll<T>(this AzureCosmosFactory azureCosmosFactory, Dictionary<string, object> dict) where T : ID
+        {
+            if (dict.Keys.Count > 0)
+            {
+                List<T> list = await azureCosmosFactory.FindByDict<T>(dict);
+
+                return await azureCosmosFactory.DeleteAll(list);
+            }
+            else
+            {
+                throw new BizException("統杅峈諾", 500);
+            }
+
+        }
+        public static async Task<List<IdPk>> DeleteAll<T>(this AzureCosmosFactory azureCosmosFactory, List<T> enyites) where T : ID
+        {
+            Type type = typeof(T);
+            string pk =AzureCosmosUtil. GetPartitionKey<T>();
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            List<IdPk> idPks = new List<IdPk>();
+            //log4net 祩??
+            string uuidKey = Guid.NewGuid().ToString();
+            string logkey = "\r\n▽" + uuidKey + "▼\r\n";
+            LogHelper.Info(default(object),
+                           logkey
+                           + "刉壺------->>\r\n"
+                           + "桶ㄩ"
+                           + type.Name + "\r\n"
+                           + "杅擂ㄩ"
+                           + enyites.ToApiJson()
+                           + "\r\n" + logkey);
+            if (container.monitor)
+            {
+                enyites = await azureCosmosFactory.DeleteTTL(enyites);
+                foreach (T t in enyites)
+                {
+                    object o = type.GetProperty(pk).GetValue(t, null);
+                    idPks.Add(new IdPk { id = t.id, pk = o.ToString(), StatusCode = HttpStatusCode.NoContent });
+                }
+                return idPks;
+            }
+            else
+            {
+                int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
+                Stopwatch stopwatch = Stopwatch.StartNew();
+                for (int i = 0; i < pages; i++)
+                {
+                    List<T> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
+                    List<KeyValuePair<PartitionKey, string>> itemsToInsert = new List<KeyValuePair<PartitionKey, string>>();
+                    lists.ForEach(x =>
+                    {
+                        object o = type.GetProperty(pk).GetValue(x, null);
+                        KeyValuePair<PartitionKey, string> keyValue = new KeyValuePair<PartitionKey, string>(new PartitionKey(o.ToString()), x.id);
+                        itemsToInsert.Add(keyValue);
+                    });
+
+                    List<Task> tasks = new List<Task>(lists.Count);
+                    itemsToInsert.ForEach(item =>
+                    {
+                        tasks.Add(container.container.DeleteItemStreamAsync(item.Value, item.Key)
+                        .ContinueWith((Task<Response> task) =>
+                        {
+                            using (Response response = task.Result)
+                            {
+
+                                idPks.Add(new IdPk { id = item.Value, pk = item.Key.ToString(), Status = response.Status });
+
+                            }
+                        }
+                        ));
+                    });
+                    await Task.WhenAll(tasks); if (container.cache && RedisHelper.Instance != null)
+                    {
+                        lists.ForEach(async x => {
+                            await RedisHelper.HDelAsync(CacheCosmosPrefix + container.container.Id, x.id);
+                        });
+                    }
+                }
+                stopwatch.Stop();
+                return idPks;
+            }
+        }
+        public static async Task<IdPk> DeleteAsync<T>(this AzureCosmosFactory azureCosmosFactory, IdPk idPk) where T : ID
+        {
+            return await DeleteAsync<T>(azureCosmosFactory, idPk.id, idPk.pk);
+        }
+        public static async Task<IdPk> DeleteAsync<T>(this AzureCosmosFactory azureCosmosFactory, string id, string pk) where T : ID
+        {
+
+            //  pk =AzureCosmosUtil.GetPartitionKey<T>();
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            if (container.monitor)
+            {
+                List<T> list = await FindByDict<T>(azureCosmosFactory,new Dictionary<string, object>() { { "id", id } });
+                if (list.Count > 0)
+                {
+                    await DeleteTTL<T>(azureCosmosFactory, list);
+                    return new IdPk { id = id, pk = pk, StatusCode = HttpStatusCode.NoContent };
+                }
+                else
+                {
+                    throw new BizException("帤梑善ID饜腔杅擂ㄛ刉壺囮啖");
+                }
+            }
+            else
+            {
+                Response response = await container.container.DeleteItemStreamAsync(id: id, partitionKey: new PartitionKey(pk));
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    await RedisHelper.HDelAsync(CacheCosmosPrefix + container.container.Id, id);
+                }
+                return new IdPk { id = id, pk = pk, Status = response.Status };
+            }
+
+        }
+        public static async Task<IdPk> DeleteAsync<T>(this AzureCosmosFactory azureCosmosFactory, T entity) where T : ID
+        {
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            string partitionKey = AzureCosmosUtil.GetPartitionKey<T>();
+            Type type = typeof(T);
+            object o = type.GetProperty(partitionKey).GetValue(entity, null);
+            if (container.monitor)
+            {
+                await DeleteTTL<T>(azureCosmosFactory, new List<T>() { entity });
+                return new IdPk { id = entity.id, pk = o.ToString(), StatusCode = HttpStatusCode.NoContent };
+            }
+            else
+            {
+                Response response = await container.container.DeleteItemStreamAsync(id: entity.id, partitionKey: new PartitionKey(o.ToString()));
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    await RedisHelper.HDelAsync(CacheCosmosPrefix + container.container.Id, entity.id);
+                }
+                return new IdPk { id = entity.id, pk = partitionKey, Status = response.Status };
+            }
+        }
+        public static async Task<List<T>> FindSQL<T>(this AzureCosmosFactory azureCosmosFactory, string sql, Dictionary<string, object> Parameters = null) where T : ID
+        {
+            if (sql.Contains(".pk"))
+            {
+                AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+                QueryRequestOptions queryOptions = GetQueryRequestOptions(GetEffectivePageSize(-1, null));
+                if (Parameters != null)
+                {
+                    AzureCosmosQuery cosmosDbQuery = new AzureCosmosQuery
+                    {
+                        QueryText = sql,
+                        Parameters = Parameters
+                    };
+                    AsyncPageable<T> feedIterator = container.container
+                    .GetItemQueryIterator<T>(cosmosDbQuery.CosmosQueryDefinition, requestOptions: queryOptions);
+                    return await ResultsFromFeedIterator(feedIterator);
+                }
+                else
+                {
+                    QueryDefinition queryDefinition = new QueryDefinition(sql);
+                    return await ResultsFromFeedIterator<T>(container.container.GetItemQueryIterator<T>(queryDefinition));
+                }
+            }
+            else
+            {
+                throw new BizException("脤戙統杅斛剕扢离 .pk ", ResponseCode.PARAMS_ERROR);
+            }
+        }
+        /// <summary>
+        /// 偌TTL刉壺
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="list"></param>
+        /// <returns></returns>
+        private static  async Task<List<T>> DeleteTTL<T>(this AzureCosmosFactory azureCosmosFactory ,List<T> list) where T : ID
+        {
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            list.ForEach(x => { x.ttl = ttl; });
+            list = await DeleteTTlALL(azureCosmosFactory,list);
+            if (container.cache && RedisHelper.Instance != null)
+            {
+                list.ForEach(async x => {
+                    await RedisHelper.HDelAsync(CacheCosmosPrefix + container.container.Id, x.id);
+                });
+            }
+            return list;
+        }
+        private static  async Task<List<T>> DeleteTTlALL<T>(this AzureCosmosFactory azureCosmosFactory, List<T> enyites) where T : ID
+        {
+            int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
+            AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
+            bool flag = false;
+            if (RedisHelper.Exists(CacheCosmosPrefix + container.container.Id))
+            {
+                flag = true;
+            }
+            string partitionKey = AzureCosmosUtil.GetPartitionKey<T>();
+            Type type = typeof(T);
+            Stopwatch stopwatch = Stopwatch.StartNew();
+            for (int i = 0; i < pages; i++)
+            {
+                List<T> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
+                List<KeyValuePair<PartitionKey, Stream>> itemsToInsert = new List<KeyValuePair<PartitionKey, Stream>>();
+                lists.ForEach(async x =>
+                {
+                    x.pk = type.Name;
+                    //x.ttl = null;
+                    MemoryStream stream = new MemoryStream();
+                    await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
+                    object o = type.GetProperty(partitionKey).GetValue(x, null);
+                    KeyValuePair<PartitionKey, Stream> keyValue = new KeyValuePair<PartitionKey, Stream>(new PartitionKey(o.ToString()), stream);
+                    itemsToInsert.Add(keyValue);
+                });
+                List<Task> tasks = new List<Task>(lists.Count);
+                itemsToInsert.ForEach(item =>
+                {
+                    tasks.Add(container.container.UpsertItemStreamAsync(item.Value, item.Key)
+                        .ContinueWith((Task<Response> task) =>
+                        {
+                            //using (ResponseMessage response = task.Result)
+                            //{
+                            //    if (!response.IsSuccessStatusCode)
+                            //    {
+                            //    }
+                            //}
+                        }
+                        ));
+                });
+                await Task.WhenAll(tasks);
+                if (container.cache && RedisHelper.Instance != null)
+                {
+                    lists.ForEach(async x => {
+                        await RedisHelper.HSetAsync(CacheCosmosPrefix + container.container.Id, x.id, x);
+                    });
+                }
+            }
+            if (container.cache && RedisHelper.Instance != null && !flag)
+            {
+                await RedisHelper.ExpireAsync(CacheCosmosPrefix + container.container.Id, timeoutSeconds);
+            }
+            stopwatch.Stop();
+            return enyites;
+        }
+        private static QueryRequestOptions GetDefaultQueryRequestOptions(int? itemsPerPage = null, int? maxBufferedItemCount = null,  int? maxConcurrency = null)
+        {
+            QueryRequestOptions queryRequestOptions = new QueryRequestOptions
+            {
+                MaxItemCount = itemsPerPage == -1 ? 1000 : itemsPerPage,
+                MaxBufferedItemCount = maxBufferedItemCount ?? 100,
+                MaxConcurrency = maxConcurrency ?? 50
+            };
+            return queryRequestOptions;
+        }
+        private static int GetEffectivePageSize(int itemsPerPage, int? maxItemCount)
+        {
+            return itemsPerPage == -1 ? maxItemCount ?? itemsPerPage : Math.Min(maxItemCount ?? itemsPerPage, itemsPerPage);
+        }
+        private static async Task<List<T>> ResultsFromQueryAndOptions<T>(this AzureCosmosFactory azureCosmosFactory, AzureCosmosQuery cosmosDbQuery, QueryRequestOptions queryOptions)
+        {
+            if (cosmosDbQuery == null)
+            {
+                return null;
+            }
+            AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
+            AsyncPageable<T> query = container.container.GetItemQueryIterator<T>(
+                queryDefinition: cosmosDbQuery.CosmosQueryDefinition,
+                requestOptions: queryOptions);
+
+            return await ResultsFromFeedIterator(query);
+        }
+        private static async Task<List<T>> ResultsFromFeedIterator<T>(AsyncPageable<T> query, int? maxItemCount = null)
+        {
+            List<T> results = new List<T>();
+             
+            await  foreach (T t in   query)
+            {
+                results.Add(t);
+                if (results.Count == maxItemCount)
+                {
+                    return results;
+                }
+            }
+            return results;
+        }
+        private static QueryRequestOptions GetQueryRequestOptions(int itemsPerPage)
+        {
+            QueryRequestOptions queryRequestOptions = new QueryRequestOptions
+            {
+                MaxItemCount = itemsPerPage
+            };
+
+            return queryRequestOptions;
+        }
+    }
+}

+ 245 - 0
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactory.cs

@@ -0,0 +1,245 @@
+using Azure;
+using Azure.Cosmos;
+using DocumentFormat.OpenXml.Office2010.ExcelAc;
+using Microsoft.Azure.Cosmos;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TEAMModelOS.Models;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
+using TEAMModelOS.SDK.Helper.Common.ReflectorExtensions;
+using ContainerProperties = Azure.Cosmos.ContainerProperties;
+using CosmosClient = Azure.Cosmos.CosmosClient;
+using CosmosClientOptions = Azure.Cosmos.CosmosClientOptions;
+using OpenXmlPowerTools;
+using System.Diagnostics;
+using System.IO;
+using System.Linq.Expressions;
+using System.Net;
+using System.Reflection;
+using System.Text;
+using System.Text.Json;
+using System.Threading;
+using TEAMModelOS.SDK.Context.Exception;
+using TEAMModelOS.SDK.DI;
+using PartitionKey = Azure.Cosmos.PartitionKey;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureCosmosFactory
+    {
+        private readonly IServiceProvider _services;
+        private readonly IOptionsMonitor<AzureCosmosFactoryOptions> _optionsMonitor;
+        private readonly ILogger _logger;
+        //private Option _option;
+        private ConcurrentDictionary<string, CosmosClient> CosmosClients { get; } = new ConcurrentDictionary<string, CosmosClient>();
+        public AzureCosmosDict CosmosDict { get; set; } = new AzureCosmosDict();
+        //   private CosmosDatabase database { get; set; }
+        
+        public AzureCosmosFactory(IServiceProvider services, IOptionsMonitor<AzureCosmosFactoryOptions> optionsMonitor, ILogger<AzureCosmosFactory> logger)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));
+            if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
+
+            _services = services;
+            _optionsMonitor = optionsMonitor;
+            _logger = logger;
+           
+            InitializeDatabase().GetAwaiter().GetResult();
+        }
+
+        /// <summary>
+        /// 取得CosmosClient,支持安全執行緒
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="region">可以使用Regions.{區域}設置,指定此屬性後,SDK會首選該區域來執行操作。此外,SDK會自動選擇後備的地理複製區域以實現高可用性。如果未指定此屬性,則SDK會將寫區域用作所有操作的首選區域</param>
+        /// <returns></returns>
+        public CosmosClient GetCosmosClient(string region = null, string name = "Default")
+        {
+            try
+            {
+                var cm = CosmosClients.GetOrAdd(name, x => new CosmosClient(_optionsMonitor.Get(name).CosmosConnectionString, new CosmosClientOptions() { ApplicationRegion = region }));
+                return cm;
+            }
+            catch (Exception e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+
+
+
+
+        /// <summary>
+        /// 调用表容器信息
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public async Task<AzureCosmosModel> InitializeCollection<T>()
+        {
+            Type type = typeof(T);
+            string partitionKey =AzureCosmosUtil. GetPartitionKey<T>();
+            CosmosDBAttribute cosmosDBAttribute = null;
+            IEnumerable<CosmosDBAttribute> attributes = type.GetCustomAttributes<CosmosDBAttribute>(true);
+            if (attributes != null && !string.IsNullOrEmpty(attributes.First<CosmosDBAttribute>().Name))
+            {
+                cosmosDBAttribute = attributes.First<CosmosDBAttribute>();
+            }
+            else
+            {
+                throw new BizException(type.Name + "未指定CosmosDB表名", ResponseCode.PARAMS_ERROR);
+            }
+            return await InitializeCollection(cosmosDBAttribute, type.Name, partitionKey);
+        }
+        /// <summary>
+        /// 调用表容器信息
+        /// </summary>
+        /// <param name="cosmosDBAttribute"></param>
+        /// <param name="typeName"></param>
+        /// <param name="PartitionKey"></param>
+        /// <returns></returns>
+        public async Task<AzureCosmosModel> InitializeCollection(CosmosDBAttribute cosmosDBAttribute, string typeName, string PartitionKey)
+        {
+            /////内存中已经存在这个表则直接返回
+            if (CosmosDict.typeCosmos.TryGetValue(typeName, out AzureCosmosModel AzureCosmosModel))
+            {
+                return AzureCosmosModel;
+            }
+            else {
+                return null;
+            }
+            ///如果没有则尝试默认创建
+            //    else
+            //    {
+            //        ContainerProperties containerProperties = new ContainerProperties { Id = cosmosDBAttribute.Name };
+            //        if (!string.IsNullOrEmpty(PartitionKey))
+            //        {
+            //            containerProperties.PartitionKeyPath = "/" + PartitionKey;
+            //        }
+            //        CosmosDatabase database = GetCosmosClient().GetDatabase(cosmosDBAttribute.Database);
+            //        CosmosContainer  containerWithConsistentIndexing =await   database.CreateContainerIfNotExistsAsync(containerProperties, throughput: cosmosDBAttribute.RU);
+            //        AzureCosmosModel cosmosModel = new AzureCosmosModel { container = containerWithConsistentIndexing, cache = cosmosDBAttribute.Cache, monitor = cosmosDBAttribute.Monitor,database= database };
+            //        CosmosDict.nameCosmos.TryAdd(cosmosDBAttribute.Name, cosmosModel);
+            //        CosmosDict.typeCosmos.TryAdd(typeName, cosmosModel);
+            //        return cosmosModel;
+            //    }
+        }
+        /// <summary>
+        /// 初始化数据配置信息
+        /// </summary>
+        /// <returns></returns>
+        public async Task InitializeDatabase()
+        {
+            int CollectionThroughput = 400;
+            string[] DatabaseIds = BaseConfigModel.Configuration.GetSection("Azure:Cosmos:Database").Get<string[]>();
+            bool isMonitor = false;
+            string leases = "leases";
+            if (DatabaseIds != null)
+            {
+                foreach (string DatabaseId in DatabaseIds)
+                {
+                    CosmosDatabase databaseDef = GetCosmosClient().GetDatabase(DatabaseId);
+                    AsyncPageable<ContainerProperties> resultSetIterator = databaseDef.GetContainerQueryIterator<ContainerProperties>();
+                    await foreach (var container in resultSetIterator)
+                    {
+                        CosmosDict.nameCosmos.TryAdd(container.Id, new AzureCosmosModel { container = databaseDef.GetContainer(container.Id), partitionKey = container.PartitionKeyPath.Replace("/", ""), cache = false, monitor = false, database = databaseDef });
+                    }
+                }
+            }
+            //获取数据库所有的表
+            List<Type> types = ReflectorExtensions.GetAllTypeAsAttribute<CosmosDBAttribute>(BaseConfigModel.Configuration.GetSection("Azure:Cosmos:ScanModel").Get<string[]>() );
+            foreach (Type type in types)
+            {
+                string PartitionKey = AzureCosmosUtil.GetPartitionKey(type);
+                string CollectionName = "";
+                int RU = 0;
+                bool cache = false;
+                bool monitor = false;
+                IEnumerable<CosmosDBAttribute> attributes = type.GetCustomAttributes<CosmosDBAttribute>(true);
+                if (attributes != null && !string.IsNullOrEmpty(attributes.First<CosmosDBAttribute>().Name))
+                {
+                    CollectionName = attributes.First<CosmosDBAttribute>().Name;
+                }
+                else
+                {
+                    throw new BizException("必须指定容器名", ResponseCode.PARAMS_ERROR);
+                }
+                if (attributes.First<CosmosDBAttribute>().Cache)
+                {
+                    cache = attributes.First<CosmosDBAttribute>().Cache;
+                }
+                if (attributes.First<CosmosDBAttribute>().Monitor)
+                {
+                    monitor = attributes.First<CosmosDBAttribute>().Monitor;
+                    if (monitor)
+                    {
+                        isMonitor = true;
+                    }
+                }
+                if (attributes.First<CosmosDBAttribute>().RU > 400)
+                {
+                    RU = attributes.First<CosmosDBAttribute>().RU;
+                }
+                else
+                {
+                    RU = CollectionThroughput;
+                }
+                //如果表存在于数据则检查RU是否变动,如果不存在则执行创建DocumentCollection
+                if (CosmosDict.nameCosmos.TryGetValue(CollectionName, out AzureCosmosModel AzureCosmosModel))
+                { //更新RU
+
+                    AzureCosmosModel.cache = cache;
+                    CosmosContainer container = GetCosmosClient().GetDatabase(attributes.First().Database).GetContainer(AzureCosmosModel.container.Id);
+                    int? throughputResponse = await container.ReadThroughputAsync();
+                    if (throughputResponse < RU)
+                    {
+                        await GetCosmosClient().GetDatabase(attributes.First().Database).GetContainer(AzureCosmosModel.container.Id).ReplaceThroughputAsync(RU);
+                    }
+                    AzureCosmosModel cosmos = new AzureCosmosModel { container = container, cache = cache, monitor = monitor, type = type, partitionKey = PartitionKey };
+                    CosmosDict.nameCosmos[CollectionName] = cosmos;
+                    CosmosDict.typeCosmos.Add(type.Name, cosmos);
+                }
+                else
+                {
+                    ContainerProperties containerProperties = new ContainerProperties { Id = CollectionName, DefaultTimeToLive = -1 };
+                    if (!string.IsNullOrEmpty(PartitionKey))
+                    {
+                        containerProperties.PartitionKeyPath = "/" + PartitionKey;
+                    }
+                    if (RU > CollectionThroughput)
+                    {
+                        CollectionThroughput = RU;
+                    }
+                    CosmosDatabase database = GetCosmosClient().GetDatabase(attributes.First().Database);
+                    CosmosContainer containerWithConsistentIndexing =await database.CreateContainerIfNotExistsAsync(containerProperties, throughput: CollectionThroughput);
+                    AzureCosmosModel cosmos = new AzureCosmosModel { container = containerWithConsistentIndexing, cache = cache, monitor = monitor, type = type, partitionKey = PartitionKey,database=database };
+                    CosmosDict.nameCosmos[CollectionName] = cosmos;
+                    CosmosDict.typeCosmos.Add(type.Name, cosmos);
+                }
+            }
+            if (isMonitor)
+            {
+                if (DatabaseIds != null)
+                {
+                    foreach (string DatabaseId in DatabaseIds)
+                    {
+                        CosmosDatabase database = GetCosmosClient().GetDatabase(DatabaseId);
+                        ContainerProperties leaseProperties = new ContainerProperties { Id = leases, PartitionKeyPath = "/id", DefaultTimeToLive = -1 };
+                        CosmosContainer leaseContainer = await database.CreateContainerIfNotExistsAsync(leaseProperties, throughput: CollectionThroughput);
+                        CosmosDict.nameCosmos.TryAdd(leases, new AzureCosmosModel { container = leaseContainer, cache = false, monitor = false, partitionKey = "/id", database = database });
+                    }
+                }
+
+            }
+        }
+        
+    }
+}

+ 20 - 0
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactoryExtensions.cs

@@ -0,0 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureCosmosFactoryExtensions
+    {
+        public static IServiceCollection AddAzureCosmos(this IServiceCollection services, string connectionString, string name = "Default")
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));            
+            if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
+            services.TryAddSingleton<AzureCosmosFactory>();
+            services.Configure<AzureCosmosFactoryOptions>(name, o => { o.Name = name; o.CosmosConnectionString = connectionString; });
+            return services;
+        }
+    }
+}

+ 14 - 0
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactoryOptions.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureCosmosFactoryOptions
+    {
+        public string Name { get; set; }
+        public string CosmosConnectionString { get; set; }
+    }
+
+   
+}

+ 18 - 0
TEAMModelOS.SDK/DI/AzureCosmos/Inner/AzureCosmosDict.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI.AzureCosmos.Inner
+{
+    public class AzureCosmosDict
+    {
+        /// <summary>
+        /// 表名方式的连接
+        /// </summary>
+        public Dictionary<string, AzureCosmosModel> nameCosmos { get; set; } = new Dictionary<string, AzureCosmosModel>();
+        /// <summary>
+        /// 类类型的连接
+        /// </summary>
+        public Dictionary<string, AzureCosmosModel> typeCosmos { get; set; } = new Dictionary<string, AzureCosmosModel>();
+    }
+}

+ 6 - 4
TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosModelInfo.cs

@@ -1,16 +1,18 @@
-using Microsoft.Azure.Cosmos;
+using Azure.Cosmos;
+using Microsoft.Azure.Cosmos;
 using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
+namespace TEAMModelOS.SDK.DI.AzureCosmos.Inner
 {
-    public class CosmosModelInfo
+    public class AzureCosmosModel
     {
-        public Container container { get; set; }
+        public CosmosContainer container { get; set; }
         public bool cache { get; set; }
         public bool monitor { get; set; } = false;
         public Type type { get; set; }
         public string partitionKey { get; set; }
+        public CosmosDatabase database { get; set; }
     }
 }

+ 6 - 6
TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosDbQuery.cs

@@ -1,11 +1,11 @@
-using Microsoft.Azure.Cosmos;
+using Azure.Cosmos;
 using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
+namespace TEAMModelOS.SDK.DI.AzureCosmos.Inner
 {
-   public class CosmosDbQuery
+    public   class AzureCosmosQuery
     {
         public string QueryText { get; set; }
 
@@ -29,14 +29,14 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
             }
         }
 
-        public CosmosDbQuery() { }
+        public AzureCosmosQuery() { }
 
-        public CosmosDbQuery(string queryText)
+        public AzureCosmosQuery(string queryText)
         {
             QueryText = queryText;
         }
 
-        public CosmosDbQuery(string queryText, Dictionary<string, object> parameters)
+        public AzureCosmosQuery(string queryText, Dictionary<string, object> parameters)
         {
             QueryText = queryText;
             Parameters = parameters;

+ 53 - 0
TEAMModelOS.SDK/DI/AzureCosmos/Inner/AzureCosmosUtil.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+using TEAMModelOS.SDK.Context.Exception;
+
+namespace TEAMModelOS.SDK.DI.AzureCosmos.Inner
+{
+   public static class AzureCosmosUtil
+    {
+        public static string GetPartitionKey<T>()
+        {
+            Type type = typeof(T);
+            return GetPartitionKey(type);
+        }
+        public static string GetPartitionKey(Type type)
+        {
+            PropertyInfo[] properties = type.GetProperties();
+            List<PropertyInfo> attrProperties = new List<PropertyInfo>();
+            foreach (PropertyInfo property in properties)
+            {
+                if (property.Name.Equals("PartitionKey"))
+                {
+                    attrProperties.Add(property);
+                    break;
+                }
+                object[] attributes = property.GetCustomAttributes(true);
+                foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
+                {
+                    if (attribute is PartitionKeyAttribute)
+                    {
+                        attrProperties.Add(property);
+                    }
+                }
+            }
+            if (attrProperties.Count <= 0)
+            {
+                throw new BizException(type.Name + " has no PartitionKey !");
+            }
+            else
+            {
+                if (attrProperties.Count == 1)
+                {
+                    return attrProperties[0].Name;
+                }
+                else { throw new BizException(type.Name + " PartitionKey can only be single!"); }
+            }
+        }
+
+
+    }
+}

+ 1 - 1
TEAMModelOS.SDK/Module/AzureCosmosDBV3/ID.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Text.Json.Serialization;
 
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
+namespace TEAMModelOS.SDK.DI
 {
     public interface ID
     {

+ 6 - 1
TEAMModelOS.SDK/Module/AzureCosmosDBV3/IdPk.cs

@@ -6,7 +6,7 @@ using System.Linq;
 using System.Net;
 using System.Threading.Tasks;
 
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
+namespace TEAMModelOS.SDK.DI
 {
     [ProtoContract]
     public class IdPk
@@ -23,5 +23,10 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
         /// </summary>
         [ProtoMember(3)]
         public HttpStatusCode StatusCode { get;set;}
+        /// <summary>
+        /// 删除状态 NoContent(删除成功),NotFound(未找到,删除失败)
+        /// </summary>
+        [ProtoMember(3)]
+        public int Status { get; set; }
     }
 }

+ 28 - 23
TEAMModelOS.SDK/Module/AzureCosmosDBV3/SQLHelperParametric.cs

@@ -8,10 +8,9 @@ using System.Text.Json;
 using System.Text.RegularExpressions;
 using TEAMModelOS.SDK.Context.Exception;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
+namespace TEAMModelOS.SDK.DI.AzureCosmos.Inner
 {
-    public class SQLHelperParametric
+   public class SQLHelper
     {
         static readonly string[] LogicOpers = new string[] { " and ", " or " };
         static readonly string[] CompareOpers = new string[] { " > ", " < ", " <= ", " >= ", " = ", " != ", " like ", " not like ", " in " };
@@ -73,7 +72,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
 
         public static bool DictIsNotNULL(Dictionary<string, object> dict)
         {
-             
+
             Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
             foreach (KeyValuePair<string, object> keyValuePair in dict)
             {
@@ -110,18 +109,20 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
             {
                 return true;
             }
-            else {
+            else
+            {
                 return false;
             }
         }
 
-        public static CosmosDbQuery GetSQL(Dictionary<string, object> dict, StringBuilder sql,string pk=null)
+        public static AzureCosmosQuery GetSQL(Dictionary<string, object> dict, StringBuilder sql, string pk = null)
         {
             if (dict != null)
             {
-                if (!DictIsNotNULL(dict)) {
+                if (!DictIsNotNULL(dict))
+                {
                     return null;
-                } 
+                }
                 Dictionary<string, object> parmeters = new Dictionary<string, object>();
 
                 int offsetNum = -1;
@@ -148,7 +149,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
 
                 //处理顺序
                 Stack<KeyValuePair<string, object>> stack = new Stack<KeyValuePair<string, object>>();
-                Dictionary<string, object> forGetParmeter = new Dictionary<string, object>(); 
+                Dictionary<string, object> forGetParmeter = new Dictionary<string, object>();
                 foreach (string item in dict.Keys)
                 {
                     if (item.EndsWith(".|"))
@@ -279,19 +280,21 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
                 {
                     sql.Append(" where 1=1 ").Append(WhereString);
                 }
-                else {
-                    sql.Append(" where c.pk='"+pk+"'").Append(WhereString);
+                else
+                {
+                    sql.Append(" where c.pk='" + pk + "'").Append(WhereString);
                 }
-                
+
 
                 if (ASC != null)
                 {
-                    sql.Append(" Order By c." + OrderByValue );
+                    sql.Append(" Order By c." + OrderByValue);
                     //sql.Append(" Order By c." + "@OrderByValue");
                 }
-                else if (DESC != null) {
+                else if (DESC != null)
+                {
                     sql.Append(" Order By c." + OrderByValue + " DESC ");
-                   // sql.Append(" Order By c." + "@OrderByValue"+ " DESC " );
+                    // sql.Append(" Order By c." + "@OrderByValue"+ " DESC " );
                 }
 
                 if (pageBool && offsetNum != -1 && limitNum != 0)
@@ -307,7 +310,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
                 parmeters = GetParmeter(forGetParmeter, parmeters, offsetNum, limitNum);
 
 
-                CosmosDbQuery cosmosDbQuery = new CosmosDbQuery
+                AzureCosmosQuery cosmosDbQuery = new AzureCosmosQuery
                 {
                     QueryText = sql.ToString(),
                     Parameters = parmeters
@@ -327,11 +330,13 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
             {
                 pageBool = true;
                 limitNum = int.Parse(limit.ToString());
-                if (limitNum < 0) {
+                if (limitNum < 0)
+                {
                     throw new BizException("PAGESIZE can't be less than 0 !");
                 }
                 offsetNum = (int.Parse(page.ToString()) - 1) * limitNum;
-                if (offsetNum < 0) {
+                if (offsetNum < 0)
+                {
                     throw new BizException("CURRPAGE can't be less than 1 !");
                 }
             }
@@ -416,7 +421,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
             }
             else if (value is JsonElement jsonElement)
             {
-                
+
                 if (jsonElement.ValueKind is JsonValueKind.Array)
                 {
                     keyListValueList = true;
@@ -429,7 +434,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
                 }
                 else
                 {
-                    if (compareOperNum != 4) keyListValueList = true; 
+                    if (compareOperNum != 4) keyListValueList = true;
                     return logicOper + key + compareOper + " @" + key1 + " ";
                 }
 
@@ -517,8 +522,8 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
             {
                 Type stype = value.GetType();
                 TypeCode typeCode = Type.GetTypeCode(stype);
-                
-                if(compareOperNum == 7) keyListValueList = true;
+
+                if (compareOperNum == 7) keyListValueList = true;
                 string sql = "";
                 if (value is string)
                 {
@@ -731,7 +736,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
             moreThan = 0, lessThan = 1, notMoreThan = 2, notLessThan = 3, equal = 4, notEqual = 5, like = 6, notLike = 7, IN = 8
         }
 
-        private static Dictionary<string, object> GetParmeter(Dictionary<string, object> dict, Dictionary<string, object> parmeters,int offset = 0,int limit = 0)
+        private static Dictionary<string, object> GetParmeter(Dictionary<string, object> dict, Dictionary<string, object> parmeters, int offset = 0, int limit = 0)
         {
             int i = 0;
             foreach (KeyValuePair<string, object> keyValue in dict)

+ 17 - 0
TEAMModelOS.SDK/DI/AzureRedis/AzureRedisExtensions.cs

@@ -0,0 +1,17 @@
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Azure.Cosmos.Table.Queryable;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Linq;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureRedisExtensions
+    {
+       
+    }
+}

+ 47 - 0
TEAMModelOS.SDK/DI/AzureRedis/AzureRedisFactory.cs

@@ -0,0 +1,47 @@
+
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Extensions.DependencyInjection;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Blobs.Specialized;
+using StackExchange.Redis;
+using System.Collections.Concurrent;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureRedisFactory
+    {
+        private readonly IServiceProvider _services;
+        private readonly IOptionsMonitor<AzureRedisFactoryOptions> _optionsMonitor;
+        private readonly ILogger _logger;
+        private ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionMultiplexers { get; } = new ConcurrentDictionary<string, ConnectionMultiplexer>();
+        public AzureRedisFactory(IServiceProvider services, IOptionsMonitor<AzureRedisFactoryOptions> optionsMonitor, ILogger<AzureRedisFactory> logger)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));
+            if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
+
+            _services = services;
+            _optionsMonitor = optionsMonitor;
+            _logger = logger;
+        }
+
+        public IDatabase GetRedisClient( int dbnum = -1,string name = "Default")
+        {           
+            try
+            {
+                var cm = ConnectionMultiplexers.GetOrAdd(name, x => ConnectionMultiplexer.Connect(_optionsMonitor.Get(name).RedisConnectionString));
+                return cm.GetDatabase(dbnum);
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+    }
+}

+ 22 - 0
TEAMModelOS.SDK/DI/AzureRedis/AzureRedisFactoryExtensions.cs

@@ -0,0 +1,22 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureRedisFactoryExtensions
+    {
+        public static IServiceCollection AddAzureRedis(this IServiceCollection services, string connectionString, string name = "Default")
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));            
+            if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
+
+            services.TryAddSingleton<AzureRedisFactory>();
+            services.Configure<AzureRedisFactoryOptions>(name, o => { o.Name = name; o.RedisConnectionString = connectionString; });
+
+            return services;
+        }
+    }
+}

+ 14 - 0
TEAMModelOS.SDK/DI/AzureRedis/AzureRedisFactoryOptions.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureRedisFactoryOptions
+    {
+        public string Name { get; set; }
+        public string RedisConnectionString { get; set; }
+    }
+
+   
+}

+ 99 - 0
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageBlobExtensions.cs

@@ -0,0 +1,99 @@
+using System.Threading.Tasks;
+using Azure.Storage;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
+using TEAMModelOS.SDK.Module.AzureBlob.Container;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.Helper.Security.ShaHash;
+using System;
+using System.IO;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureStorageBlobExtensions
+    {
+        /// <summary>
+        /// 取得指定前置詞的 Blob 名稱的總大小(Bytes),例如指定目錄名稱為前置詞
+        /// </summary>      
+        /// <param name="prefix">篩選開頭名稱,Null代表容器總大小</param>
+        /// <returns>總大小(Bytes),如果為Null代表查無前置詞或者發生錯誤</returns>
+        public static async Task<long?> GetBlobsSize(this BlobContainerClient client, string prefix = null)
+        {
+            long? size = 0;
+            try
+            {                
+                await foreach (var item in client.GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix))
+                {
+                    size += item.Properties.ContentLength;
+                };
+
+                return size;
+            }
+            catch 
+            {
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 系统管理员 资源,题目关联,htex关联,学习活动学生上传文件关联,基本信息关联,教室平面图关联,评测冷数据关联
+        /// "system": [ "res", "item", "htex", "task", "info", "room", "exam" ],
+        /// 资源,题目关联,htex关联,学习活动学生上传文件关联,基本信息关联,教室平面图关联,评测冷数据关联
+        /// "school": [ "res", "item", "htex", "task", "info", "room", "exam" ],
+        /// 资源,题目关联,htex关联,学习活动关联,教师基本信息关联
+        /// "teacher": [ "res", "item", "htex", "task", "info" ],
+        /// 答案及学习活动上传的文件,学生基本信息关联
+        ///"student": [ "stu/{studentId}/ans", "stu/{studentId}/task" ]
+        /// </summary>
+        /// <param name="name">容器名称</param>
+        /// <param name="text">文件内容的流</param>
+        /// <param name="folder">业务文件夹</param>
+        /// <param name="fileName">文件名</param>
+        /// <param name="contentTypeDefault">是否存放文件后缀对应的contentType</param>
+        /// <returns></returns>
+        public static async Task<AzureBlobModel> UploadFileByContainer(this AzureStorageFactory azureStorageFactory, string name, string text, string folder, string fileName, bool contentTypeDefault = true)
+        {
+
+            // string groupName =folder;
+
+            BlobContainerClient blobContainer =  azureStorageFactory.GetBlobContainerClient(name.ToLower().Replace("#", "")); //blobClient.GetContainerReference(groupName); 
+            Uri url = blobContainer.Uri;
+
+            var blockBlob = blobContainer.GetBlobClient(folder + "/" + fileName);
+            string fileext = fileName.Substring(fileName.LastIndexOf(".") > 0 ? fileName.LastIndexOf(".") : 0);
+            string content_type = "application/octet-stream";
+            if (!contentTypeDefault)
+            {
+                ContentTypeDict.dict.TryGetValue(fileext, out string contenttype);
+                if (!string.IsNullOrEmpty(contenttype))
+                {
+                    content_type = contenttype;
+                    
+                    
+                }
+                else
+                {
+                   
+                    //blockBlob.Properties.ContentType = content_type;
+                }
+            }
+            else
+            {
+               
+                //blockBlob.Properties.ContentType = content_type;
+            }
+            byte[] bytes = System.Text.Encoding.Default.GetBytes(text);
+            Stream streamBlob= new MemoryStream(bytes);
+            await blockBlob.UploadAsync(streamBlob);
+            blockBlob.SetHttpHeaders(new BlobHttpHeaders { ContentType = content_type });
+            AzureBlobModel model = new AzureBlobModel(fileName, name, folder, fileName, folder, content_type, bytes.Length)
+            {
+                Sha1Code = ShaHashHelper.GetSHA1(bytes),
+                BlobUrl = blockBlob.Uri.ToString()
+            };
+            return model;
+        }
+
+    }
+}

+ 350 - 0
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactory.cs

@@ -0,0 +1,350 @@
+
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Extensions.DependencyInjection;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Blobs.Specialized;
+using Azure.Storage.Sas;
+using Azure.Storage;
+using TEAMModelOS.SDK.Extension;
+using Azure.Storage.Queues;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureStorageFactory
+    {
+        private readonly IServiceProvider _services;
+        private readonly IOptionsMonitor<AzureStorageFactoryOptions> _optionsMonitor;
+        private readonly ILogger _logger;
+        public AzureStorageFactory(IServiceProvider services, IOptionsMonitor<AzureStorageFactoryOptions> optionsMonitor, ILogger<AzureStorageFactory> logger)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));
+            if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
+
+            _services = services;
+            _optionsMonitor = optionsMonitor;
+            _logger = logger;
+        }
+
+        public BlobServiceClient GetBlobServiceClient(string name = "Default")
+        {            
+            try
+            {
+                var options = _optionsMonitor.Get(name);
+                return new BlobServiceClient(options.StorageAccountConnectionString);
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+
+        }
+
+        public BlobContainerClient GetBlobContainerClient(string containerName, string name = "Default")
+        {            
+            try
+            {
+                var options = _optionsMonitor.Get(name);
+                return new BlobContainerClient(options.StorageAccountConnectionString, containerName);
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+        
+        public BlobBatchClient GetBlobBatchClient(string name = "Default")
+        {           
+            try
+            {
+                var options = _optionsMonitor.Get(name);
+                BlobServiceClient blobServiceClient = new BlobServiceClient(options.StorageAccountConnectionString);
+                return blobServiceClient.GetBlobBatchClient();
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 取得Blob Container SAS (有效期預設一天)
+        /// </summary>
+        /// <param name="containerName">容器名稱</param>        
+        /// <param name="blobContainerSasPermissions">權限(可多選)Flags</param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public (string uri ,string sas) GetBlobContainerSAS(string containerName, BlobContainerSasPermissions blobContainerSasPermissions, string name = "Default")
+        {
+            try
+            {
+                var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString);
+                var accountname = keys["AccountName"];
+                var accountkey = keys["AccountKey"];
+                var endpoint = keys["EndpointSuffix"];
+
+                var blobSasBuilder = new BlobSasBuilder
+                {
+                    StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)),
+                    ExpiresOn = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0)),
+                    BlobContainerName = containerName
+                };
+
+                blobSasBuilder.SetPermissions(blobContainerSasPermissions);
+                var sskc = new StorageSharedKeyCredential(accountname, accountkey);
+                BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc);
+                UriBuilder fullUri = new UriBuilder()
+                {
+                    Scheme = "https",
+                    Host = $"{accountname}.blob.{endpoint}",
+                    Path = containerName
+                    //Query = sasQueryParameters.ToString()
+                };
+
+                return (fullUri.Uri.ToString(), sasQueryParameters.ToString());
+            }
+            catch
+            {
+                return (null, null);
+            }
+        }
+
+        /// <summary>
+        /// 取得Blob Container SAS (有效期預設一天)
+        /// </summary>
+        /// <param name="containerName">容器名稱</param>
+        /// <param name="blobName"></param>
+        /// <param name="blobContainerSasPermissions"></param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public BlobAuth GetContainerSasUri(BlobSas blobSas, bool isRead, string name = "Default")
+        {
+            try
+            {
+                string containerName = null;
+                var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString);
+                var accountname = keys["AccountName"];
+                var accountkey = keys["AccountKey"];
+                var endpoint = keys["EndpointSuffix"];
+                if (blobSas.role == "system")
+                {
+                    containerName = "teammodelos";
+                }
+                else
+                {
+                    containerName = blobSas.name.ToLower().Replace("#", "");
+                }
+                DateTimeOffset dateTime = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0));
+                long time = dateTime.ToUnixTimeMilliseconds();
+                var blobSasBuilder = new BlobSasBuilder
+                {
+                    StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)),
+                    ExpiresOn = dateTime,
+                    BlobContainerName = containerName
+                };
+                BlobContainerSasPermissions blobContainerSasPermissions = BlobContainerSasPermissions.Read;
+                if (isRead) {
+                    blobContainerSasPermissions = BlobContainerSasPermissions.Read;
+                }
+                else {
+                    blobContainerSasPermissions = BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Create | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List;
+                }
+                blobSasBuilder.SetPermissions(blobContainerSasPermissions);
+                var sskc = new StorageSharedKeyCredential(accountname, accountkey);
+                BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc);
+                UriBuilder fullUri = new UriBuilder()
+                {
+                    Scheme = "https",
+                    Host = $"{accountname}.blob.{endpoint}",
+                    Path = containerName
+                    //Query = sasQueryParameters.ToString()
+                };
+                return new BlobAuth { url = fullUri.Uri.ToString(), sas = sasQueryParameters.ToString(), timeout = time, name = containerName };
+               // return (fullUri.Uri.ToString(), sasQueryParameters.ToString());
+            }
+            catch
+            {
+                return   null ;
+            }
+        }
+
+        /// <summary>
+        /// 取得Blob SAS (有效期預設一天)
+        /// </summary>
+        /// <param name="containerName">容器名稱</param>
+        /// <param name="blobName"></param>
+        /// <param name="blobSasPermissions">權限(可多選)Flags</param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public string GetBlobSAS(string containerName, string blobName, BlobSasPermissions blobSasPermissions, string name = "Default")
+        {
+            try
+            {
+                var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString);
+                var accountname = keys["AccountName"];
+                var accountkey = keys["AccountKey"];
+                var endpoint = keys["EndpointSuffix"];
+
+                var blobSasBuilder = new BlobSasBuilder
+                {
+                    StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)),
+                    ExpiresOn = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0)),
+                    BlobContainerName = containerName,
+                    BlobName = blobName
+                };
+
+                blobSasBuilder.SetPermissions(blobSasPermissions);
+                var sskc = new StorageSharedKeyCredential(accountname, accountkey);
+                BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc);
+                UriBuilder fullUri = new UriBuilder()
+                {
+                    Scheme = "https",
+                    Host = $"{accountname}.blob.{endpoint}",
+                    Path = $"{containerName}/{blobName}",
+                    Query = sasQueryParameters.ToString()
+                };
+
+                return fullUri.Uri.ToString();
+            }
+            catch
+            {
+                return null;
+            }
+        }
+
+
+        /// <summary>
+        /// 取得Blob SAS (有效期預設一天)
+        /// </summary>
+        /// <param name="containerName">容器名稱</param>
+        /// <param name="blobName"></param>
+        /// <param name="blobSasPermissions"></param>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public BlobAuth GetBlobSasUriRead(string containerName, string blobName,string name = "Default")
+        {
+            try
+            {
+                var keys = Utils.ParseConnectionString(_optionsMonitor.Get(name).StorageAccountConnectionString);
+                var accountname = keys["AccountName"];
+                var accountkey = keys["AccountKey"];
+                var endpoint = keys["EndpointSuffix"];
+                DateTimeOffset dateTime = DateTimeOffset.UtcNow.Add(new TimeSpan(1, 0, 15, 0));
+                long time = dateTime.ToUnixTimeMilliseconds();
+                var blobSasBuilder = new BlobSasBuilder
+                {
+                    StartsOn = DateTimeOffset.UtcNow.Subtract(new TimeSpan(0, 15, 0)),
+                    ExpiresOn = dateTime,
+                    BlobContainerName = containerName,
+                    BlobName = blobName
+                };
+
+                blobSasBuilder.SetPermissions(BlobSasPermissions.Read);
+                var sskc = new StorageSharedKeyCredential(accountname, accountkey);
+                BlobSasQueryParameters sasQueryParameters = blobSasBuilder.ToSasQueryParameters(sskc);
+                UriBuilder fullUri = new UriBuilder()
+                {
+                    Scheme = "https",
+                    Host = $"{accountname}.blob.{endpoint}",
+                    Path = $"{containerName}/{blobName}",
+                    Query = sasQueryParameters.ToString()
+                };
+                return new BlobAuth { url = fullUri.Uri.ToString(), sas = sasQueryParameters.ToString(), timeout = time };
+               // return fullUri.Uri.ToString();
+            }
+            catch
+            {
+                return null;
+            }
+        }
+
+        public CloudTableClient GetCloudTableClient(string name = "Default")
+        {            
+            try
+            {
+                var options = _optionsMonitor.Get(name);
+                CloudStorageAccount storageAccount = CloudStorageAccount.Parse(options.StorageAccountConnectionString);
+                return storageAccount.CreateCloudTableClient();
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+
+       
+
+        /// <summary>
+        /// 可讓您管理儲存體帳戶中的所有佇列
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public QueueServiceClient GetQueueServiceClient(string name = "Default")
+        {            
+            try
+            {
+                var options = _optionsMonitor.Get(name);
+                return new QueueServiceClient(options.StorageAccountConnectionString);
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 可讓您管理和操作個別佇列及其訊息
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="queueName"></param>
+        /// <returns></returns>
+        public QueueClient GetQueueClient(string queueName, string name = "Default")
+        {
+            if (name == null) throw new ArgumentNullException(nameof(name));
+            try
+            {
+                var options = _optionsMonitor.Get(name);
+                return new QueueClient(options.StorageAccountConnectionString, queueName);
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+        public  async Task<CloudTable> InitializeTable<T>()
+        {
+            string TableName = GetTableSpace<T>();
+            CloudTable cloudTable = GetCloudTableClient().GetTableReference(TableName);
+            await cloudTable.CreateIfNotExistsAsync();
+            return cloudTable;
+        }
+        private string GetTableSpace<T>()
+        {
+            Type type = typeof(T);
+            string Name = type.Name;
+            object[] attributes = type.GetCustomAttributes(true);
+            foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
+            {
+                if (attribute is TableNameAttribute tableSpace)
+                {
+                    Name = tableSpace.Name;
+                }
+            }
+            return Name;
+        }
+    }
+}

+ 22 - 0
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactoryExtensions.cs

@@ -0,0 +1,22 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureStorageFactoryExtensions
+    {
+        public static IServiceCollection AddAzureStorage(this IServiceCollection services, string connectionString,string name = "Default")
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));            
+            if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
+
+            services.TryAddSingleton<AzureStorageFactory>();
+            services.Configure<AzureStorageFactoryOptions>(name, o => { o.Name = name; o.StorageAccountConnectionString = connectionString; });
+
+            return services;
+        }
+    }
+}

+ 14 - 0
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactoryOptions.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureStorageFactoryOptions
+    {
+        public string Name { get; set; }
+        public string StorageAccountConnectionString { get; set; }
+    }
+
+   
+}

+ 516 - 0
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageTableExtensions.cs

@@ -0,0 +1,516 @@
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Azure.Cosmos.Table.Queryable;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Linq;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using System.Reflection;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureStorageTableExtensions
+    {
+ 
+        #region CloudTable 批次操作    
+
+        /// <summary>
+        /// 批次新增資料至Table儲存區。
+        /// </summary>
+        /// <param name="entities">欲快取的集合</param>
+        /// <returns></returns>
+        public static async Task<TableBatchResult> BatchInsertAsync<T>(this CloudTable table, IEnumerable<T> entities) where T : ITableEntity, new()
+        {
+            TableBatchOperation batchOperation = new TableBatchOperation();
+            foreach (var cache in entities)
+            {
+                batchOperation.Insert(cache);
+            }
+
+            return await table.ExecuteBatchAsync(batchOperation);
+        }
+
+        #endregion
+
+        #region CloudTable Get
+
+        /// <summary>
+        /// (同步)取得 table 中指定 PartitionKey 的所有集合。
+        /// </summary>
+        /// <returns></returns>
+        public static IEnumerable<T> Get<T>(this CloudTable table, string partitionKey) where T : ITableEntity, new()
+        {
+            TableQuery<T> query = new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey));
+            return table.ExecuteQuery(query);
+        }
+
+        /// <summary>
+        /// (同步)取得指定 PartitionKey與 RowKey 的數據,效能:點查詢,最佳。
+        /// </summary>
+        /// <typeparam name="T">T</typeparam>       
+        /// <param name="partitionKey">PartitionKey</param>   
+        /// <param name="rowKey">RowKey</param>  
+        /// <returns></returns>
+        public static T Get<T>(this CloudTable table, string partitionKey, string rowKey) where T : ITableEntity, new()
+        {
+            TableOperation retrieveOperation = TableOperation.Retrieve<T>(partitionKey, rowKey);
+            var retrieveResult = table.Execute(retrieveOperation);
+            if (retrieveResult.Result != null)
+            {
+                //DynamicTableEntityJsonSeria1lizer
+                return (T)retrieveResult.Result;
+            }
+            else
+            {
+                return default(T);
+            }
+        }
+
+        public static DynamicTableEntity Get(this CloudTable table, string partitionKey, string rowKey)
+        {
+            TableOperation retrieveOperation = TableOperation.Retrieve(partitionKey, rowKey);
+            var retrieveResult = table.Execute(retrieveOperation);
+            if (retrieveResult.Result != null)
+            {
+                return retrieveResult.Result as DynamicTableEntity;
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 取得指定 PartitionKey 的所有集合(分頁),效能:範圍查詢,次佳。
+        /// </summary>
+        /// <typeparam name="T">T</typeparam>       
+        /// <param name="partitionKey">PartitionKey</param>
+        /// <param name="takeCount">指定每次返回數量</param>
+        /// <param name="specifyPropertys">指定只須返回的屬性,效能:伺服器端預測,降低延遲和成本</param>
+        /// <param name="onProgress">要返回集合的委派</param>
+        /// <param name="ct">CancellationToken</param>
+        /// <returns></returns>
+        public static async Task GetAsync<T>(this CloudTable table, string partitionKey, int? takeCount = null, List<string> specifyPropertys = null, Action<IList<T>> onProgress = null, CancellationToken ct = default(CancellationToken)) where T : ITableEntity, new()
+        {
+            TableQuery<T> tableQuery = null;
+            TableContinuationToken token = null;
+            var filter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey);
+
+            if (specifyPropertys != null)
+                tableQuery = new TableQuery<T>().Where(filter).Select(specifyPropertys);
+            else
+                tableQuery = new TableQuery<T>().Where(filter);
+
+            if (takeCount != null) tableQuery.TakeCount = takeCount;
+
+            do
+            {
+                var queryResponse = await table.ExecuteQuerySegmentedAsync(tableQuery, token);
+                token = queryResponse.ContinuationToken;
+                onProgress?.Invoke(queryResponse.Results);
+            } while (token != null && !ct.IsCancellationRequested);
+        }
+
+        /// <summary>
+        /// 取得指定 PartitionKey 的所有集合,效能:範圍查詢,次佳。
+        /// </summary>
+        /// <typeparam name="T">T</typeparam>       
+        /// <param name="partitionKey">PartitionKey</param>
+        /// <param name="takeCount">指定每次返回數量</param>
+        /// <param name="specifyPropertys">指定只須返回的屬性,效能:伺服器端預測,降低延遲和成本</param>
+        /// <param name="onProgress">要返回集合的委派</param>
+        /// <param name="ct">CancellationToken</param>
+        /// <returns></returns>
+        public static async Task<IEnumerable<T>> GetAsync<T>(this CloudTable table, string partitionKey, int? takeCount = null, List<string> specifyPropertys = null, CancellationToken ct = default(CancellationToken)) where T : ITableEntity, new()
+        {
+            TableQuery<T> tableQuery = null;
+            TableContinuationToken token = null;
+            var filter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey);
+
+            if (specifyPropertys != null)
+                tableQuery = new TableQuery<T>().Where(filter).Select(specifyPropertys);
+            else
+                tableQuery = new TableQuery<T>().Where(filter);
+
+            if (takeCount != null) tableQuery.TakeCount = takeCount;
+            var items = new List<T>();
+
+            do
+            {
+                var queryResponse = await table.ExecuteQuerySegmentedAsync(tableQuery, token);
+                token = queryResponse.ContinuationToken;
+                items.AddRange(queryResponse.Results);
+            } while (token != null && !ct.IsCancellationRequested);
+            return items;
+        }
+
+        /// <summary>
+        /// 傳回指定partitionKey的Count數量
+        /// </summary>        
+        /// <param name="partitionKey"></param>
+        /// <returns></returns>
+        public static int GetCount(this CloudTable table, string partitionKey)
+        {           
+
+            TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey)).Select(new List<string> { "PartitionKey" });
+            var queryResponse = table.ExecuteQuery(query).ToList();
+            return queryResponse.Count();
+        }
+
+        #endregion
+
+        #region CloudTable Get All
+        /// <summary>
+        /// (同步)取得 table 的所有集合,效能:資料表掃描,不佳。
+        /// </summary>
+        /// <returns></returns>
+        public static IEnumerable<T> GetAll<T>(this CloudTable table) where T : ITableEntity, new()
+        {
+            return table.ExecuteQuery(new TableQuery<T>());
+        }
+
+        /// <summary>
+        /// 取得 table 的所有集合(分頁),效能:資料表掃描,不佳。
+        /// </summary>
+        /// <param name="takeCount">指定每次返回數量</param>
+        /// <param name="specifyPropertys">指定只須返回的屬性,效能:伺服器端預測,降低延遲和成本</param>
+        /// <param name="onProgress">要返回集合的委派</param>
+        /// <returns></returns>        
+        public static async Task GetAllAsync<T>(this CloudTable table, int? takeCount = null, List<string> specifyPropertys = null, Action<IList<T>> onProgress = null, CancellationToken ct = default(CancellationToken)) where T : ITableEntity, new()
+        {
+            TableContinuationToken token = null;
+            TableQuery<T> tableQuery = new TableQuery<T>();
+            if (specifyPropertys != null)
+                tableQuery = new TableQuery<T>().Select(specifyPropertys);
+            else
+                tableQuery = new TableQuery<T>();
+            if (takeCount != null) tableQuery.TakeCount = takeCount;
+            var items = new List<T>();
+
+            do
+            {
+                var queryResponse = await table.ExecuteQuerySegmentedAsync(tableQuery, token);
+                token = queryResponse.ContinuationToken;
+                items.AddRange(queryResponse.Results);
+                onProgress?.Invoke(queryResponse.Results);
+            } while (token != null && !ct.IsCancellationRequested);
+        }
+
+        /// <summary>
+        /// 取得 table 的所有集合,效能:資料表掃描,不佳。
+        /// </summary>
+        /// <param name="takeCount">指定每次返回數量</param>
+        /// <param name="specifyPropertys">指定只須返回的屬性,效能:伺服器端預測,降低延遲和成本</param>       
+        /// <returns></returns>        
+        public static async Task<IEnumerable<T>> GetAllAsync<T>(this CloudTable table, int? takeCount = null, List<string> specifyPropertys = null, CancellationToken ct = default(CancellationToken)) where T : ITableEntity, new()
+        {
+            TableContinuationToken token = null;
+            TableQuery<T> tableQuery = new TableQuery<T>();
+            if (takeCount != null) tableQuery.TakeCount = takeCount;
+            if (specifyPropertys != null)
+                tableQuery = new TableQuery<T>().Select(specifyPropertys);
+            else
+                tableQuery = new TableQuery<T>();
+            var items = new List<T>();
+
+            do
+            {
+                var queryResponse = await table.ExecuteQuerySegmentedAsync(tableQuery, token);
+                token = queryResponse.ContinuationToken;
+                items.AddRange(queryResponse.Results);
+            } while (token != null && !ct.IsCancellationRequested);
+            return items;
+        }
+        #endregion
+
+        public static async Task<T> Save<T>(this AzureStorageFactory azureStorageFactory, TableEntity entity) where T : TableEntity, new()
+        {
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            TableOperation operation = TableOperation.Insert(entity);
+            TableResult result = await TableName.ExecuteAsync(operation);
+            return (T)result.Result;
+        }
+        public static async Task<T> SaveOrUpdate<T>(this AzureStorageFactory azureStorageFactory, TableEntity entity) where T : TableEntity, new()
+        {
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            TableOperation operation = TableOperation.InsertOrReplace(entity);
+            TableResult result = await TableName.ExecuteAsync(operation);
+            return (T)result.Result;
+        }
+
+        public static async Task<T> Update<T>(this AzureStorageFactory azureStorageFactory, TableEntity entity) where T : TableEntity, new()
+        {
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            TableOperation operation = TableOperation.Replace(entity);
+            TableResult result = await TableName.ExecuteAsync(operation);
+            return (T)result.Result;
+        }
+
+        public static async Task<T> Delete<T>(this AzureStorageFactory azureStorageFactory, TableEntity entity) where T : TableEntity, new()
+        {
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            TableOperation operation = TableOperation.Delete(entity);
+            TableResult result = await TableName.ExecuteAsync(operation);
+            return (T)result.Result;
+        }
+
+        public static async Task<List<T>> DeleteAll<T>(this AzureStorageFactory azureStorageFactory,  List<T> entitys) where T : TableEntity, new()
+        {
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                     
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.Delete(lists[j]);
+                        }
+                        result = await TableName.ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
+            return entitys;
+        }
+
+        public static async Task<List<T>> SaveOrUpdateAll<T>(this AzureStorageFactory azureStorageFactory, List<T> entitys) where T : TableEntity, new()
+        {
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.InsertOrReplace(lists[j]);
+                        }
+                        result = await TableName.ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
+            return entitys;
+        }
+        public static async Task<List<T>> UpdateAll<T>(this AzureStorageFactory azureStorageFactory, List<T> entitys) where T : TableEntity, new()
+        {
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                  
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.Replace(lists[j]);
+                        }
+                        result = await TableName.ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
+            return entitys;
+        }
+        public static async Task<List<T>> SaveAll<T>(this AzureStorageFactory azureStorageFactory, List<T> entitys) where T : TableEntity, new()
+        {
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                  
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.Insert(lists[j]);
+                        }
+                        result = await TableName.ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
+            return entitys;
+        }
+
+        public static async Task<List<T>> FindListByDict<T>(this AzureStorageFactory azureStorageFactory, Dictionary<string, object> dict) where T : TableEntity, new()
+        {
+            CloudTable TableName = await azureStorageFactory.InitializeTable<T>();
+            var exQuery = new TableQuery<T>();
+            StringBuilder builder = new StringBuilder();
+            if (null != dict && dict.Count > 0)
+            {
+                var keys = dict.Keys;
+                int index = 1;
+                foreach (string key in keys)
+                {
+                    if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
+                    {
+                        string typeStr = SwitchType<T>(dict[key], key);
+                        if (string.IsNullOrEmpty(typeStr))
+                        {
+                            continue;
+                        }
+                        if (index == 1)
+                        {
+                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append(typeStr);
+
+                        }
+                        else
+                        {
+                            //builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append("  " + TableOperators.And + "  " + typeStr);
+
+                        }
+                        index++;
+                    }
+                    else
+                    {
+                        throw new Exception("The parameter must have value!");
+                    }
+                }
+
+                exQuery.Where(builder.ToString());
+                return await QueryList<T>(exQuery, TableName);
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+
+
+        private static async Task<List<T>> QueryList<T>(TableQuery<T> exQuery, CloudTable TableName  ) where T : TableEntity, new()
+        {
+            TableContinuationToken continuationToken = null;
+            List<T> entitys = new List<T>();
+            do
+            {
+                var result = await TableName.ExecuteQuerySegmentedAsync(exQuery, continuationToken);
+                if (result.Results.Count > 0)
+                {
+                    entitys.AddRange(result.ToList());
+                }
+                continuationToken = result.ContinuationToken;
+            } while (continuationToken != null);
+            return entitys;
+        }
+
+        private static string SwitchType<T>(object obj, string key)
+        {
+            Type objType = typeof(T);
+            PropertyInfo property = objType.GetProperty(key);
+
+            //Type s = obj.GetType();
+            //TypeCode typeCode = Type.GetTypeCode(s);
+            if (property == null)
+            {
+                //return null;
+                throw new Exception(objType.FullName + " PropertyInfo doesn't include this parameter :" + key);
+            }
+            TypeCode typeCode = Type.GetTypeCode(property.PropertyType);
+
+
+            switch (typeCode)
+            {
+
+                case TypeCode.String: return TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, obj.ToString());
+                case TypeCode.Int32: return TableQuery.GenerateFilterConditionForInt(key, QueryComparisons.Equal, int.Parse(obj.ToString()));
+                case TypeCode.Double: return TableQuery.GenerateFilterConditionForDouble(key, QueryComparisons.Equal, (double)obj);
+                case TypeCode.Byte: return TableQuery.GenerateFilterConditionForBinary(key, QueryComparisons.Equal, (byte[])obj);
+                case TypeCode.Boolean: return TableQuery.GenerateFilterConditionForBool(key, QueryComparisons.Equal, (bool)obj);
+                case TypeCode.DateTime: return TableQuery.GenerateFilterConditionForDate(key, QueryComparisons.Equal, (DateTimeOffset)obj);
+                case TypeCode.Int64: return TableQuery.GenerateFilterConditionForLong(key, QueryComparisons.Equal, long.Parse(obj.ToString()));
+                default: return null;
+            }
+        }
+    }
+}

+ 114 - 0
TEAMModelOS.SDK/DI/DingDing/DingDing.cs

@@ -0,0 +1,114 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Net.Http;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Security.Cryptography;
+using TEAMModelOS.SDK.Extension;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class DingDing
+    {
+        private const string url = "https://oapi.dingtalk.com/robot/send?access_token=";
+        private readonly HttpClient _httpClient;
+
+        public DingDing(HttpClient httpClient)
+        {
+            _httpClient = httpClient;
+        }
+
+        // <summary>
+        /// 發送需要加簽驗證的Bot訊息(msgtype為text)
+        /// </summary>
+        /// <param name="robotUrl">釘釘Robot發送Url</param>
+        /// <param name="secret">加簽密鑰</param>
+        /// <param name="msg">發送訊息</param>
+        /// <returns></returns>
+        public async Task SendBotMsg(string msg, GroupNames groupkey)
+        {
+            JObject jObject = new JObject()
+            {
+                new JProperty("msgtype","text"),
+                new JProperty("text",new JObject(
+                    new JProperty("content",msg)))
+            };
+            var content = new StringContent(jObject.ToString(), Encoding.UTF8, "application/json");
+            var keys = groupkey.GetDescriptionText().Split(',');
+            if (keys.Length == 1) await _httpClient.PostAsync($"{url}{keys[0]}", content);
+            else
+            {
+                var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                await _httpClient.PostAsync($"{url}{keys[0]}&timestamp={timestamp}&sign={BotAddSign(keys[1], timestamp)}", content);
+            }
+        }
+
+        // <summary>
+        /// 發送需要加簽驗證的Bot訊息(msgtype為text)
+        /// </summary>
+        /// <param name="robotUrl">釘釘Robot發送Url</param>
+        /// <param name="secret">加簽密鑰</param>
+        /// <param name="msg">發送訊息</param>
+        /// <returns></returns>
+        public async Task SendBotMsg(string msg, string accesstoken, string secret = null)
+        {
+            JObject jObject = new JObject()
+            {
+                new JProperty("msgtype","text"),
+                new JProperty("text",new JObject(
+                    new JProperty("content",msg)))
+            };
+
+            var content = new StringContent(jObject.ToString(), Encoding.UTF8, "application/json");
+            if (string.IsNullOrWhiteSpace(secret))
+                await _httpClient.PostAsync($"{url}{accesstoken}", content);
+            else
+            {
+                var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                await _httpClient.PostAsync($"{url}{accesstoken}&timestamp={timestamp}&sign={BotAddSign(secret, timestamp)}", content);
+            }
+
+
+        }
+
+        #region private
+        /// <summary>
+        /// 釘釘Bot簽名生成方法
+        /// </summary>
+        /// <param name="zTime"></param>
+        /// <returns></returns>
+        private static string BotAddSign(string secret, long zTime)
+        {
+            //"SEC6a6822db6567f79854a474002407cd9ac36da4d194b5fb79e073c35ef61119ed";
+            string stringToSign = zTime + "\n" + secret;
+            var encoding = new System.Text.ASCIIEncoding();
+            byte[] keyByte = encoding.GetBytes(secret);
+            byte[] messageBytes = encoding.GetBytes(stringToSign);
+            using (var hmacsha256 = new HMACSHA256(keyByte))
+            {
+                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
+                return System.Web.HttpUtility.UrlEncode(Convert.ToBase64String(hashmessage), Encoding.UTF8);
+            }
+        }
+        #endregion
+    }
+
+    public enum GroupNames
+    {
+        [Description("ce63217d9c734a92fd91c7c9ceaa9b25e109cce94615a7f75288dc43865a6e20,SEC6a6822db6567f79854a474002407cd9ac36da4d194b5fb79e073c35ef61119ed")]
+        研發C組,
+        [Description("2c5ced0725b592b1a96f1fb800d6d9a15727986ef75923a838a4d24e6b8c9147,SEC66ff954306c1fd98b5b160e23c253649f22205e69a16fb26e18d136f49875a9e")]
+        客戶回饋群組,
+        [Description("f8bf19c9363e3b288e018856014bcbf89708f19b3aae009e203edd68af25c9fe")]
+        BB訂單群組,
+        [Description("a27b099b15a054374da41b9f66f72e5fc6b378e98418859f7c0ef46408941808")]
+        測試群組,
+        [Description("1a316ce4edc2db88231d40d80072b00f2751d7d9e2e5871c5dc061885b01c48d,SECff60201ac9b219943b9f8fc397fda1a617d0cbc140850f5ea9cb4f131479d39a")]
+        醍摩豆服務運維群組
+    }
+
+
+}

+ 154 - 0
TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeID.cs

@@ -0,0 +1,154 @@
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class SnowflakeId
+    {
+        private readonly IOptionsMonitor<SnowflakeIDOptions> _optionsMonitor;
+
+        // 開始時間截((new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc)-Jan1st1970).TotalMilliseconds)
+        private const long twepoch = 1577836800000L;
+        // 機器ID所佔的位數
+        private const int workerIdBits = 5;
+        // 數據標識ID所佔的位數
+        private const int datacenterIdBits = 5;
+        // 支持的最大機器ID,結果是31 (這個移位算法可以很快的計算出幾位二進制數所能表示的最大十進制數)
+        private const long maxWorkerId = -1L ^ (-1L << workerIdBits);
+        // 支持的最大數據標識ID,結果是31
+        private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+        // 序列在ID中佔的位數 
+        private const int sequenceBits = 12;
+        // 數據標識ID向左移17位(12+5)
+        private const int datacenterIdShift = sequenceBits + workerIdBits;
+        // 機器ID向左移12位 
+        private const int workerIdShift = sequenceBits;
+        // 時間截向左移22位(5+5+12)
+        private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+        // 生成序列的掩碼,這里為4095 (0b111111111111=0xfff=4095)
+        private const long sequenceMask = -1L ^ (-1L << sequenceBits);
+        // 毫秒內序列(0~4095) 
+        private long sequence = 0L;
+        // 上次生成ID的時間截 
+        private long lastTimestamp = -1L;
+
+
+        // 數據中心ID(0~31,China請填8,Global請填1)
+        public long DatacenterId { get; private set; }
+        // 工作機器ID(0~31,依照數據中心,各地區自定)
+        public long WorkerId { get; private set; }
+
+
+
+        /// <summary>
+        /// 分散式ID產生器 (Snowflake算法,支援線程安全)
+        /// </summary>
+        /// <param name="datacenterId">數據中心ID (0~31)</param>
+        /// <param name="workerId">工作機器ID (0~31)</param>
+        public SnowflakeId(IOptionsMonitor<SnowflakeIDOptions> optionsMonitor)
+        {
+            if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
+            _optionsMonitor = optionsMonitor;
+            this.DatacenterId = optionsMonitor.CurrentValue.DatacenterId;
+            this.WorkerId = optionsMonitor.CurrentValue.WorkerId;
+        }
+
+        /// <summary>
+        /// 獲得下一個ID
+        /// </summary>
+        /// <returns></returns>
+        public long NextId()
+        {
+            lock (this)
+            {
+                long timestamp = GetCurrentTimestamp();
+                if (timestamp > lastTimestamp) //時間戳改變,毫秒內序列重置
+                {
+                    sequence = 0L;
+                }
+                else if (timestamp == lastTimestamp) //如果是同一時間生成的,則進行毫秒內序列
+                {
+                    sequence = (sequence + 1) & sequenceMask;
+                    if (sequence == 0) //毫秒內序列溢出
+                    {
+                        timestamp = GetNextTimestamp(lastTimestamp); //阻塞到下一個毫秒,獲得新的時間戳
+                    }
+                }
+                else   //當前時間小於上一次ID生成的時間戳,證明系統時鐘被回撥,此時需要做回撥處理
+                {
+                    sequence = (sequence + 1) & sequenceMask;
+                    if (sequence > 0)
+                    {
+                        timestamp = lastTimestamp;     //停留在最後一次時間戳上,等待系統時間追上後即完全度過了時鐘回撥問題
+                    }
+                    else   //毫秒內序列溢出
+                    {
+                        timestamp = lastTimestamp + 1;   //直接進位到下一個毫秒                          
+                    }
+                    //throw new Exception(string.Format("Clock moved backwards.  Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
+                }
+
+                lastTimestamp = timestamp;       //上次生成ID的時間截
+
+                //移位並通過或運算拼到一起組成64位的ID
+                var id = ((timestamp - twepoch) << timestampLeftShift)
+                        | (DatacenterId << datacenterIdShift)
+                        | (WorkerId << workerIdShift)
+                        | sequence;
+                return id;
+            }
+        }
+
+        /// <summary>
+        /// 解析分散式ID
+        /// </summary>
+        /// <returns></returns>
+        public string ParseId(long Id)
+        {
+            StringBuilder sb = new StringBuilder();
+
+            var timestamp = (Id >> timestampLeftShift);
+            var time = Jan1st1970.AddMilliseconds(timestamp + twepoch);
+            sb.Append(time.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss:fff"));
+
+            var datacenterId = (Id ^ (timestamp << timestampLeftShift)) >> datacenterIdShift;
+            sb.Append("_" + datacenterId);
+
+            var workerId = (Id ^ ((timestamp << timestampLeftShift) | (datacenterId << datacenterIdShift))) >> workerIdShift;
+            sb.Append("_" + workerId);
+
+            var sequence = Id & sequenceMask;
+            sb.Append("_" + sequence);
+
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// 阻塞到下一個毫秒,直到獲得新的時間戳
+        /// </summary>
+        /// <param name="lastTimestamp">上次生成ID的時間截</param>
+        /// <returns>當前時間戳</returns>
+        private static long GetNextTimestamp(long lastTimestamp)
+        {
+            long timestamp = GetCurrentTimestamp();
+            while (timestamp <= lastTimestamp)
+            {
+                timestamp = GetCurrentTimestamp();
+            }
+            return timestamp;
+        }
+
+        /// <summary>
+        /// 獲取當前時間戳
+        /// </summary>
+        /// <returns></returns>
+        private static long GetCurrentTimestamp()
+        {
+            return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
+        }
+
+        private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+    }
+}

+ 28 - 0
TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeIDExtensions.cs

@@ -0,0 +1,28 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class SnowflakeIDExtensions
+    {
+        /// <summary>
+        /// 分散式ID產生器 (Snowflake算法,支援線程安全)
+        /// </summary>
+        /// <param name="datacenterId">數據中心ID (0~31)</param>
+        /// <param name="workerId">工作機器ID (0~31)</param>
+        public static IServiceCollection AddSnowflakeId(this IServiceCollection services, long datacenterId, long workerId)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));            
+            if (datacenterId > 31 || datacenterId < 0) throw new Exception("datacenterId only 0-31");            
+            if (workerId > 31 || workerId < 0) throw new Exception("workerId only 0-31");
+            
+            services.TryAddSingleton<SnowflakeId>();
+            services.Configure<SnowflakeIDOptions>(o => { o.DatacenterId = datacenterId; o.WorkerId = workerId; });
+
+            return services;
+        }
+    }
+}

+ 20 - 0
TEAMModelOS.SDK/DI/SnowflakeID/SnowflakeIDOptions.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class SnowflakeIDOptions
+    {
+        /// <summary>
+        /// 數據中心ID (0~31)
+        /// </summary>
+        public long DatacenterId { get; set; }
+        /// <summary>
+        /// 工作機器ID (0~31)
+        /// </summary>
+        public long WorkerId { get; set; }
+    }
+
+   
+}

+ 2 - 2
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/AzureJsonRequest.cs

@@ -1,9 +1,9 @@
-using TEAMModelOS.SDK.Extension.DataResult.RequestData;
+using TEAMModelOS.SDK;
 using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest
+namespace TEAMModelOS.SDK
 {
     /// <summary>
     /// 

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/BaseJosnRequest.cs

@@ -1,7 +1,7 @@
 
 using System;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest
+namespace TEAMModelOS.SDK
 {
     
     public abstract class BaseJosnRequest

+ 2 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/JosnRequest.cs

@@ -3,11 +3,12 @@ using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest
+namespace TEAMModelOS.SDK
 {
     
     public class JosnRequest<T>:BaseJosnRequest
     {
+
         public T @params { get; set; }
     }
 }

+ 6 - 6
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/PaginationRequest.cs

@@ -1,15 +1,15 @@
 
 
-using TEAMModelOS.SDK.Extension.DataResult.RequestData;
+using TEAMModelOS.SDK;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest
+namespace TEAMModelOS.SDK
 {
-    public  class PaginationRequest<T> : BaseJosnRequest
+    public  class PaginationJsonRequest<T> : BaseJosnRequest
     {
-        public PaginationRequest()
+        public PaginationJsonRequest()
         {
-            @params = new RequestData.PaginationRequest<T>();
+            @params = new PaginationRequest<T>();
         }
-        public RequestData.PaginationRequest<T> @params { get; set; }
+        public PaginationRequest<T> @params { get; set; }
     }
 }

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/BaseResponse.cs

@@ -1,7 +1,7 @@
 
 using Microsoft.VisualBasic;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class BaseResponse 

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/DataJsonResponse.cs

@@ -3,7 +3,7 @@ using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class DataJsonResponse<T> : BaseResponse

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/EmptyJosnResponse.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     public class EmptyJosnResponse :BaseResponse
     {

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorJosnResponse.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
 
     public class ErrorJosnResponse : BaseResponse

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorModel.cs

@@ -2,7 +2,7 @@
 
 using System.Collections.Generic;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
    

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/JsonRPCResult.cs

@@ -3,7 +3,7 @@ using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class JsonRPCResult<T>

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJosnResponse.cs

@@ -3,7 +3,7 @@ using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class PageJosnResponse<T> : BaseResponse

+ 2 - 2
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJsonResult.cs

@@ -1,7 +1,7 @@
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
+using TEAMModelOS.SDK;
 
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class PageJsonResult<T> : JsonRPCResult<T>

+ 2 - 2
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ResponseBuilder.cs

@@ -1,10 +1,10 @@
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
+using TEAMModelOS.SDK;
 
 using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public  class ResponseBuilder

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJosnResponse.cs

@@ -3,7 +3,7 @@ using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class TokenJosnResponse<T>: BaseResponse

+ 2 - 2
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJsonResult.cs

@@ -1,10 +1,10 @@
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
+using TEAMModelOS.SDK;
 
 using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse
+namespace TEAMModelOS.SDK
 {
     
     public class TokenJsonResult<T> : JsonRPCResult<T>

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/PageToken/AzurePagination.cs

@@ -1,7 +1,7 @@
 
 using System.Collections.Generic;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.PageToken
+namespace TEAMModelOS.SDK
 {
     
     public class AzurePagination<T>

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/PageToken/AzureTableToken.cs

@@ -1,7 +1,7 @@
 
 using System.ComponentModel.DataAnnotations;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.PageToken
+namespace TEAMModelOS.SDK
 {
     
     public class AzureTableToken

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/PageToken/Pagination.cs

@@ -2,7 +2,7 @@
 using System;
 using System.Collections.Generic;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.PageToken
+namespace TEAMModelOS.SDK
 {
     
     public class Pagination

+ 2 - 2
TEAMModelOS.SDK/Extension/DataResult/RequestData/AzureTokenRequest.cs

@@ -1,9 +1,9 @@
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
+using TEAMModelOS.SDK;
 using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.RequestData
+namespace TEAMModelOS.SDK
 {
    public class AzureTokenRequest<T> :BaseRequest
    {

+ 1 - 1
TEAMModelOS.SDK/Extension/DataResult/RequestData/BaseRequest.cs

@@ -1,7 +1,7 @@
 using System;
 using System.Collections.Generic;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.RequestData
+namespace TEAMModelOS.SDK
 {
     public class BaseRequest
     {

+ 2 - 2
TEAMModelOS.SDK/Extension/DataResult/RequestData/PaginationRequest.cs

@@ -1,6 +1,6 @@
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
+using TEAMModelOS.SDK;
 
-namespace TEAMModelOS.SDK.Extension.DataResult.RequestData
+namespace TEAMModelOS.SDK
 {
     public class PaginationRequest<T> : BaseRequest
     {

+ 22 - 0
TEAMModelOS.SDK/Extension/EnumExtensions.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Reflection;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Extension
+{
+    public static class EnumExtensions
+    {
+        /// <summary>
+        /// 取得Enum描述值
+        /// </summary>       
+        public static string GetDescriptionText(this Enum source)
+        {
+            FieldInfo fi = source.GetType().GetField(source.ToString());
+            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
+            if (attributes.Length > 0) return attributes[0].Description;
+            else return source.ToString();
+        }
+    }
+}

+ 94 - 0
TEAMModelOS.SDK/Extension/HttpContextExtensions.cs

@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Primitives;
+
+namespace TEAMModelOS.SDK.Extension
+{
+    public static class HttpContextExtensions
+    {
+        /// <summary>
+        /// 取得驗證金鑰,Authorization
+        /// </summary>        
+        public static string GetToken(this HttpContext httpContext)
+        {
+            return httpContext.Request.Headers["Authorization"].ToString();
+        }
+
+        /// <summary>
+        /// 取得JWT驗證金鑰,Authorization Bearer
+        /// </summary>
+        /// <param name="httpContext"></param>
+        /// <returns></returns>
+        public static string GetJwtToken(this HttpContext httpContext)
+        {
+            var token = string.Empty;
+            string authorization = httpContext.Request.Headers["Authorization"].ToString();
+            if (!string.IsNullOrWhiteSpace(authorization) && authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
+            {
+                token = authorization.Substring("Bearer ".Length).Trim();
+            }
+            return token;
+        }
+
+        /// <summary>
+        /// 取得遠端呼叫的IP
+        /// </summary>        
+        public static string GetRemoteIP(this HttpContext httpContext)
+        {            
+                return httpContext?.Connection?.RemoteIpAddress?.ToString();            
+        }
+
+        /// <summary>
+        /// 取得X-Auth-Key值
+        /// </summary>        
+        /// <param name="key">Key Name</param>
+        /// <returns></returns>
+        public static string GetXAuth(this HttpContext httpContext, string key = null)
+        {
+            try
+            {
+                if (httpContext.Request.Headers.TryGetValue($"X-Auth-{key}", out StringValues value))
+                    return value.ToString();
+                else
+                    return null;
+            }
+            catch
+            {
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 取得User-Agent值
+        /// </summary>       
+        public static string GetUserAgent(this HttpContext httpContext)
+        {
+            try
+            {
+                return httpContext.Request.Headers["User-Agent"].ToString();
+            }
+            catch
+            {
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 取得Scheme值
+        /// </summary>      
+        public static string GetScheme(this HttpContext httpContext)
+        {           
+                return httpContext?.Request?.Scheme;           
+        }
+
+        /// <summary>
+        /// 取得HostName值
+        /// </summary>        
+        public static string GetHostName(this HttpContext httpContext)
+        {            
+                return httpContext?.Request?.Host.ToString();          
+        }
+    }
+}

+ 52 - 0
TEAMModelOS.SDK/Extension/JsonExtensions.cs

@@ -0,0 +1,52 @@
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.Json;
+
+namespace TEAMModelOS.SDK.Extension
+{
+    public static class JsonExtensions
+    {
+        public static string ToJsonString(this JsonDocument jdoc)
+        {
+            var bufferWriter = new ArrayBufferWriter<byte>();
+            using var writer = new Utf8JsonWriter(bufferWriter, new JsonWriterOptions { Indented = true });
+            jdoc.WriteTo(writer);
+            writer.Flush();
+            return Encoding.UTF8.GetString(bufferWriter.WrittenSpan);
+        }
+
+        public static string ToJsonString(this JsonElement jelement)
+        {
+            var bufferWriter = new ArrayBufferWriter<byte>();
+            using var writer = new Utf8JsonWriter(bufferWriter, new JsonWriterOptions { Indented = true });
+            jelement.WriteTo(writer);
+            writer.Flush();
+            return Encoding.UTF8.GetString(bufferWriter.WrittenSpan);
+        }
+
+        public static string ToJsonString(this Object obj, JsonSerializerOptions option = null)
+        {
+            var json = JsonSerializer.Serialize(obj, option);
+            return json;
+        }
+
+        public static T ToObject<T>(this JsonDocument jdoc, JsonSerializerOptions options = null)
+        {
+            return jdoc.RootElement.ToObject<T>(options);
+        }
+
+        public static T ToObject<T>(this JsonElement jelement, JsonSerializerOptions options = null)
+        {
+            var bufferWriter = new ArrayBufferWriter<byte>();
+            using var writer = new Utf8JsonWriter(bufferWriter);
+            jelement.WriteTo(writer);
+            writer.Flush();
+            return JsonSerializer.Deserialize<T>(bufferWriter.WrittenSpan, options);
+        }        
+
+        
+    }
+}

+ 13 - 10
TEAMModelOS.SDK/Extension/MessagePush/Implements/SendCloudService.cs

@@ -1,17 +1,19 @@
-
+
 using TEAMModelOS.SDK.Extension.MessagePush.Interfaces;
 using TEAMModelOS.SDK.Extension.MessagePush.Model;
 using System;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using TEAMModelOS.SDK.Extension.Language.Interfaces;
-using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+
 using Microsoft.Extensions.Options;
 using TEAMModelOS.SDK.Extension.Language.Model;
 using TEAMModelOS.SDK.Helper.Common.JsonHelper;
 using TEAMModelOS.SDK.Helper.Security.Md5Hash;
 using TEAMModelOS.SDK.Helper.Network.HttpHelper;
 using TEAMModelOS.SDK.Extension.HttpClient.Implements;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.DI;
 
 namespace TEAMModelOS.SDK.Extension.MessagePush.Implements
 {
@@ -19,9 +21,9 @@ namespace TEAMModelOS.SDK.Extension.MessagePush.Implements
     {
         public SmsSendCloud smsSendCloud;
         public ILanguageService _languageService;
-        public IAzureTableDBRepository _azureTableDBRepository;
+        public AzureStorageFactory _azureTableDBRepository;
         public HttpClientSendCloud _httpClientService;
-        public SendCloudService(IOptions<SmsSendCloud> _option, ILanguageService languageService , IAzureTableDBRepository azureTableDBRepository , HttpClientSendCloud httpClientService )
+        public SendCloudService(IOptions<SmsSendCloud> _option, ILanguageService languageService , AzureStorageFactory azureTableDBRepository , HttpClientSendCloud httpClientService )
         {
             _azureTableDBRepository = azureTableDBRepository;
             _languageService = languageService;
@@ -53,11 +55,11 @@ namespace TEAMModelOS.SDK.Extension.MessagePush.Implements
                     {
                         { "BizNum", BizNum },{ "BizCode", BizCode["code"] }, { "Language", Language["code"] } ,
                     };
-                    SmsConfig smsConfig = await _azureTableDBRepository.FindOneByDict<SmsConfig>(dict);
+                    List<SmsConfig> smsConfig = await _azureTableDBRepository.FindListByDict<SmsConfig>(dict);
 
-                    if (smsConfig != null && smsConfig.RowKey != null)
+                    if (smsConfig.IsNotEmpty()  && smsConfig[0].RowKey != null)
                     {
-                        smsConfigs.Add(smsConfig);
+                        smsConfigs.Add(smsConfig[0]);
                     }
                     else {
                         DateTimeOffset now = DateTimeOffset.Now;
@@ -104,12 +106,13 @@ namespace TEAMModelOS.SDK.Extension.MessagePush.Implements
             {
                 { "BizNum", BizNum },{ "BizCode", BizCode }, { "Language", SmsLang } ,
             };
-            SmsConfig smsConfig   =  await _azureTableDBRepository.FindOneByDict<SmsConfig>(dict);
+            List<SmsConfig> smsConfig = await _azureTableDBRepository.FindListByDict<SmsConfig>(dict);
 
-            if (smsConfig != null && smsConfig.RowKey != null )
+            if (smsConfig.IsNotEmpty() && smsConfig[0].RowKey != null)
             {
+             
                 //默认调用英文,不管是否包含,发送时会去处理相关信息
-                int.TryParse(smsConfig.Template ,out templateId);
+                int.TryParse(smsConfig[0].Template ,out templateId);
             }
             //else {
             //    throw new BizException("");

+ 94 - 0
TEAMModelOS.SDK/Extension/Utils.cs

@@ -0,0 +1,94 @@
+using Microsoft.AspNetCore.Cryptography.KeyDerivation;
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Extension
+{
+    public class Utils
+    {
+        private static RNGCryptoServiceProvider _random = new RNGCryptoServiceProvider();
+
+        public static string HashedPassword(string password, string salt)
+        {
+            byte[] hashBytes = KeyDerivation.Pbkdf2(
+                password: password,
+                salt: Encoding.UTF8.GetBytes(salt), //SHA1鹽(8-20字節),SHA256(32字節)
+                prf: KeyDerivationPrf.HMACSHA1,
+                iterationCount: 10000, //hash次數,越多次代表破解難度變高,但效能會差點
+                numBytesRequested: 256 / 8 //指定得出結果長度
+            );
+
+            string hashText = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
+            return hashText;
+        }
+
+        /// <summary>
+        /// 建立真隨機字串(CSPRNG),適用密碼、鹽
+        /// </summary>
+        /// <param name="stringLength">長度</param>
+        /// <param name="key">要限制的字元串(長度需大於等於8),如果為null或者小於8,預設為"abcdefghijklmnopqrstuvwxyz1234567890"</param>
+        /// <returns></returns>
+        public static string CreatSaltString(int stringLength, string key = null)
+        {
+            ReadOnlySpan<char> span;
+            if (key == null || key.Length < 8)
+                span = "abcdefghijklmnopqrstuvwxyz1234567890";
+            else
+                span = key.AsSpan();
+
+            int length = span.Length;
+            StringBuilder randomString = new StringBuilder(length);
+            for (int i = 0; i < stringLength; ++i)
+            {
+                randomString.Append(span[SetRandomSeeds(length)]);
+            }
+            return randomString.ToString();
+        }
+
+        /// <summary>
+        /// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
+        /// </summary>
+        /// <param name="max">最大值</param>
+        public static int CreatSaltInt(int max)
+        {
+            var bytes = new byte[4];
+            _random.GetBytes(bytes);
+            int value = BitConverter.ToInt32(bytes, 0);
+            value = value % (max + 1);
+            if (value < 0) value = -value;
+            return value;
+        }
+
+        /// <summary>
+        /// 建立真隨機整數數字(CSPRNG),適用亂數、隨機編號
+        /// </summary>
+        /// <param name="min">最小值</param>
+        /// <param name="max">最大值</param>
+        public static int CreatSaltInt(int min, int max)
+        {
+            int value = CreatSaltInt(max - min) + min;
+            return value;
+        }        
+
+        public static Dictionary<string, string> ParseConnectionString(string connectionString)
+        {
+            var d = new Dictionary<string, string>();
+            foreach (var item in connectionString.Split(';',StringSplitOptions.RemoveEmptyEntries))
+            {
+                var a = item.IndexOf('=');
+                d.Add(item.Substring(0, a), item.Substring(a + 1));
+            }
+            return d;
+        }
+
+        private static int SetRandomSeeds(int length)
+        {
+            decimal maxValue = (decimal)long.MaxValue;
+            byte[] array = new byte[8];
+            _random.GetBytes(array);
+            return (int)(Math.Abs(BitConverter.ToInt64(array, 0)) / maxValue * length);
+        }
+    }
+}

+ 1 - 1
TEAMModelOS.SDK/Helper/Security/RSACrypt/RSAUtils.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.IO;
 using System.Security.Cryptography;
 namespace TEAMModelOS.SDK.Helper.Security.RSACrypt

+ 44 - 44
TEAMModelOS.SDK/Module/AzureBlob/Configuration/AzureBlobServiceCollectionExtensions.cs

@@ -1,48 +1,48 @@
-using TEAMModelOS.SDK.Module.AzureBlob.Implements;
-using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
-using Microsoft.Extensions.DependencyInjection;
+////using TEAMModelOS.SDK.Module.AzureBlob.Implements;
+//using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
+//using Microsoft.Extensions.DependencyInjection;
 
-namespace TEAMModelOS.SDK.Module.AzureBlob.Configuration
-{
-    public static class AzureBlobServiceCollectionExtensions
-    {
-        public static AzureBlobServiceBuilder Builder { get; set; }
+//namespace TEAMModelOS.SDK.Module.AzureBlob.Configuration
+//{
+//    public static class AzureBlobServiceCollectionExtensions
+//    {
+//        public static AzureBlobServiceBuilder Builder { get; set; }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        /// <returns></returns>
-        private static AzureBlobServiceBuilder AddServerBuilder(this IServiceCollection services)
-        {
-            return new AzureBlobServiceBuilder(services);
-        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="services"></param>
+//        /// <returns></returns>
+//        private static AzureBlobServiceBuilder AddServerBuilder(this IServiceCollection services)
+//        {
+//            return new AzureBlobServiceBuilder(services);
+//        }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        /// <returns></returns>
-        public static AzureBlobServiceBuilder AddAzureBlobStorage(this IServiceCollection services)
-        {
-            if (Builder == null)
-            {
-                Builder = services.AddServerBuilder();
-            }
-            services.AddSingleton<IAzureBlobDBRepository, AzureBlobDBRepository>();
-            return Builder;
-        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="services"></param>
+//        /// <returns></returns>
+//        public static AzureBlobServiceBuilder AddAzureBlobStorage(this IServiceCollection services)
+//        {
+//            if (Builder == null)
+//            {
+//                Builder = services.AddServerBuilder();
+//            }
+//            services.AddSingleton<IAzureBlobDBRepository, AzureBlobDBRepository>();
+//            return Builder;
+//        }
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="builder"></param>
-        /// <param name="_connectionString"></param>
-        /// <returns></returns>
-        public static AzureBlobServiceBuilder AddConnection(this AzureBlobServiceBuilder builder, AzureBlobOptions databaseOptions)
-        {
-            builder.Services.AddSingleton(databaseOptions);
-            return builder;
-        }
-    }
-}
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="builder"></param>
+//        /// <param name="_connectionString"></param>
+//        /// <returns></returns>
+//        public static AzureBlobServiceBuilder AddConnection(this AzureBlobServiceBuilder builder, AzureBlobOptions databaseOptions)
+//        {
+//            builder.Services.AddSingleton(databaseOptions);
+//            return builder;
+//        }
+//    }
+//}

+ 38 - 38
TEAMModelOS.SDK/Module/AzureBlob/Configuration/BlobClientSingleton.cs

@@ -1,43 +1,43 @@
-
-using Microsoft.WindowsAzure.Storage;
-using Microsoft.WindowsAzure.Storage.Blob;
-using System;
 
-namespace TEAMModelOS.SDK.Module.AzureBlob.Configuration
-{
-    public sealed class BlobClientSingleton
-    {
-        private static string _connectionString;
-        private CloudBlobClient BlobClient;
+//using Microsoft.WindowsAzure.Storage;
+//using Microsoft.WindowsAzure.Storage.Blob;
+//using System;
 
-        private BlobClientSingleton() { }
+//namespace TEAMModelOS.SDK.Module.AzureBlob.Configuration
+//{
+//    public sealed class BlobClientSingleton
+//    {
+//        private static string _connectionString;
+//        private CloudBlobClient BlobClient;
 
-        public CloudBlobClient GetBlobClient()
-        {
-            if (BlobClient != null)
-            {
-                return BlobClient;
-            }
-            else
-            {
-                getInstance(_connectionString);
-                return BlobClient;
-            }
-        }
+//        private BlobClientSingleton() { }
 
-        public static BlobClientSingleton getInstance(string connectionString)
-        {
-            _connectionString = connectionString;
-            return SingletonInstance.instance;
-        }
+//        public CloudBlobClient GetBlobClient()
+//        {
+//            if (BlobClient != null)
+//            {
+//                return BlobClient;
+//            }
+//            else
+//            {
+//                getInstance(_connectionString);
+//                return BlobClient;
+//            }
+//        }
 
-        private static class SingletonInstance
-        {
-            public static BlobClientSingleton instance = new BlobClientSingleton()
-            {
-                BlobClient = CloudStorageAccount.Parse(_connectionString).CreateCloudBlobClient()
-               //BlobClient = new  CloudBlobClient(new Uri(_connectionString))
-            };
-        }
-    }
-}
+//        public static BlobClientSingleton getInstance(string connectionString)
+//        {
+//            _connectionString = connectionString;
+//            return SingletonInstance.instance;
+//        }
+
+//        private static class SingletonInstance
+//        {
+//            public static BlobClientSingleton instance = new BlobClientSingleton()
+//            {
+//                BlobClient = CloudStorageAccount.Parse(_connectionString).CreateCloudBlobClient()
+//               //BlobClient = new  CloudBlobClient(new Uri(_connectionString))
+//            };
+//        }
+//    }
+//}

+ 0 - 1
TEAMModelOS.SDK/Module/AzureBlob/Configuration/BlobFileDto.cs

@@ -1,4 +1,3 @@
-using Microsoft.WindowsAzure.Storage.Blob;
 using System;
 using System.Collections.Generic;
 using System.Text;

Файловите разлики са ограничени, защото са твърде много
+ 956 - 943
TEAMModelOS.SDK/Module/AzureBlob/Implements/AzureBlobDBRepository.cs


+ 1 - 2
TEAMModelOS.SDK/Module/AzureBlob/Interfaces/IAzureBlobDBRepository.cs

@@ -1,9 +1,8 @@
-using TEAMModelOS.SDK.Module.AzureBlob.Container;
+using TEAMModelOS.SDK.Module.AzureBlob.Container;
 using Microsoft.AspNetCore.Http;
 using System.Collections.Generic;
 using System.Threading.Tasks;
 using System.IO;
-using Microsoft.WindowsAzure.Storage.Blob;
 using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
 
 namespace TEAMModelOS.SDK.Module.AzureBlob.Interfaces

+ 0 - 19
TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/AzureCosmosDBOptions.cs

@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration
-{
-    public class AzureCosmosDBOptions
-    {
-        public string ConnectionString { get; set; } = null;
-        public string ConnectionKey { get; set; } = null;
-        public string Database { get; set; } = null;
-        public int CollectionThroughput { get; set; } = 400;
-        public string[] ScanModel { get; set; }
-        public AzureCosmosDBOptions()
-        {
-            //Azure Table Init
-        }
-    }
-}

+ 0 - 24
TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/AzureCosmosDBServiceBuilder.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration
-{
-    public class AzureCosmosDBServiceBuilder
-    {
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        public AzureCosmosDBServiceBuilder(IServiceCollection services)
-        {
-            Services = services ?? throw new ArgumentNullException(nameof(services));
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        public IServiceCollection Services { get; }
-    }
-}

+ 0 - 45
TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/AzureCosmosDBServiceCollectionExtensions.cs

@@ -1,45 +0,0 @@
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Implements;
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Interfaces;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration
-{
-    public static class AzureCosmosDBServiceCollectionExtensions
-    {
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        /// <returns></returns>
-        private static AzureCosmosDBServiceBuilder AddCosmosDBServerBuilder(this IServiceCollection services)
-        {
-            return new AzureCosmosDBServiceBuilder(services);
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        /// <returns></returns>
-        public static AzureCosmosDBServiceBuilder AddAzureCosmosDB(this IServiceCollection services)
-        {
-            var builder = services.AddCosmosDBServerBuilder();
-            services.AddSingleton<IAzureCosmosDBRepository, AzureCosmosDBRepository>();
-            return builder;
-        }
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="builder"></param>
-        /// <param name="_connectionString"></param>
-        /// <returns></returns>
-        public static AzureCosmosDBServiceBuilder AddCosmosDBConnection(this AzureCosmosDBServiceBuilder builder, AzureCosmosDBOptions databaseOptions)
-        {
-            builder.Services.AddSingleton(databaseOptions);
-            return builder;
-        }
-    }
-}

+ 0 - 49
TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/CosmosDBClientSingleton.cs

@@ -1,49 +0,0 @@
-using Microsoft.Azure.Documents.Client;
-using System;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration
-{
-    public sealed class CosmosDBClientSingleton
-    {
-        private static string _connectionUrl;
-        private static string _connectionKey;
-        private DocumentClient CosmosClient;
-
-        private CosmosDBClientSingleton() { }
-
-
-
-        public DocumentClient GetCosmosDBClient()
-        {
-            if (CosmosClient != null)
-            {
-                return CosmosClient;
-            }
-            else
-            {
-                getInstance(_connectionUrl, _connectionKey);
-                return CosmosClient;
-            }
-        }
-
-        public static CosmosDBClientSingleton getInstance(string connectionUrl, string connectionKey)
-        {
-            _connectionUrl = connectionUrl;
-            _connectionKey = connectionKey;
-            return SingletonInstance.instance;
-        }
-
-        private static class SingletonInstance
-        {
-            public static CosmosDBClientSingleton instance = new CosmosDBClientSingleton()
-            {
-                CosmosClient = new DocumentClient(new Uri(_connectionUrl), _connectionKey, ConnectionPolicy)
-            };
-            private static readonly ConnectionPolicy ConnectionPolicy = new ConnectionPolicy
-            {
-                ConnectionMode = ConnectionMode.Direct,
-                ConnectionProtocol = Protocol.Tcp
-            };
-        }
-    }
-}

+ 0 - 864
TEAMModelOS.SDK/Module/AzureCosmosDB/Configuration/SQLHelper.cs

@@ -1,864 +0,0 @@
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using TEAMModelOS.SDK.Context.Exception;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration
-{
-    public class SQLHelper
-    {
-        static readonly string[] LogicOpers = new string[] { " and ", " or " };
-        static readonly string[] CompareOpers = new string[] { " > ", " < ", " <= ", " >= ", " = ", " != ", " like ", " not like ", " in " };
-
-
-        public static void ReplaceKeyWords(ref StringBuilder sql)
-        {
-            sql.Replace(".order.", "['order'].");
-            sql.Replace(".order ", "['order'] ");
-
-            sql.Replace(".group.", "['group'].");
-            sql.Replace(".group ", "['group'] ");
-
-            sql.Replace(".end.", "['end'].");
-            sql.Replace(".end ", "['end'] ");
-
-            sql.Replace(".having.", "['having'].");
-            sql.Replace(".having ", "['having'] ");
-        }
-
-        public static void GetSQL(Dictionary<string, object> dict, ref StringBuilder sql)
-        {
-
-            if (dict != null)
-            {
-                int offsetNum = 0;
-                int limitNum = 0;
-                bool pageBool = false;
-                GetPageNum(dict, ref offsetNum, ref limitNum, ref pageBool);
-
-
-                //处理顺序
-                Stack<KeyValuePair<string, object>> stack = new Stack<KeyValuePair<string, object>>();
-
-                foreach (string item in dict.Keys)
-                {
-                    if (item.EndsWith(".|"))
-                    {
-                        stack.Push(new KeyValuePair<string, object>(item, dict[item]));
-                    }
-
-                }
-                foreach (string item in dict.Keys)
-                {
-                    if (!item.EndsWith(".|"))
-                    {
-                        stack.Push(new KeyValuePair<string, object>(item, dict[item]));
-                    }
-
-                }
-
-
-                string Join = " join ";
-                string instring = " in ";
-                Dictionary<string, string> keyValues = new Dictionary<string, string>();
-                StringBuilder WhereString = new StringBuilder();
-                int heada = 0;
-                string[] sqlHead = new string[] { "A", "B", "C", "D", "E", "F" };
-                int kslength = 0;
-                int logicOperNum = 0;
-
-                bool keyListValueList = true;
-                string distinctHead = "select distinct value(c) from c ";
-
-
-                int stackCount = stack.Count;
-                //foreach (KeyValuePair<string, object> item in newDict)
-                for (int k = 0; k < stackCount; k++)
-                {
-                    KeyValuePair<string, object> item = stack.Pop();
-                    bool isLikeSQL = false;
-                    if (item.Key.StartsWith("$.") || item.Key.StartsWith("!$."))
-                    {
-                        isLikeSQL = true;
-                    }
-
-
-                    string key = item.Key;
-                    string[] keyHead = key.Split(".");
-                    int index = 0;
-                    int compareOper = 4;
-                    int logicOper = 0;
-
-                    if (key.EndsWith(".&"))
-                    {
-                        logicOper = (int)LogicOper.and;
-                        key = key.Replace(".&", "");
-                    }
-                    else if (key.EndsWith(".|"))
-                    {
-                        logicOper = (int)LogicOper.or;
-                        key = key.Replace(".|", "");
-                    }
-                    CompareOperSwitch(keyHead[0], ref key, ref compareOper);
-                    string[] keyBody = key.Split("[*]");
-                    if (keyBody.Length > 1)
-                    {
-                        kslength += keyBody.Length;
-                        if (kslength < (7 + heada))
-                        {
-                            StringBuilder sqlitem = new StringBuilder();
-                            for (int i = 0; i < keyBody.Length - 1; i++)
-                            {
-                                //Console.WriteLine(ks[i]);
-                                if (i == 0)
-                                {
-                                    sqlitem.Append(Join);
-                                    string a = sqlHead[heada] + index;
-                                    sqlitem.Append(a + " ");
-                                    //keyValues.Add(ks[i], a);
-                                    keyValues[keyBody[i]] = a;
-                                    sqlitem.Append(instring);
-                                    sqlitem.Append("c.");
-                                    sqlitem.Append(keyBody[i]);
-                                }
-                                else
-                                {
-                                    sqlitem.Append(Join);
-                                    string a = sqlHead[heada] + index;
-                                    sqlitem.Append(a + " ");
-                                    //keyValues.Add(ks[i], a);
-                                    keyValues[keyBody[i]] = a;
-                                    sqlitem.Append(instring);
-                                    sqlitem.Append(keyValues[keyBody[i - 1]]);
-                                    sqlitem.Append(keyBody[i]);
-                                }
-                                index += 1;
-                            }
-                            sql.Append(sqlitem);
-                            string s = "";
-                            if (isLikeSQL)
-                            {
-                                if (item.Value is JArray array)
-                                {
-                                    s = ValueIsLike(sqlHead[heada] + (keyBody.Length - 2) + keyBody[index] + "", array, LogicOpers[logicOper], logicOperNum, compareOper, ref keyListValueList);
-                                }
-                                else if (item.Value is IEnumerable enumerable && !(item.Value is String))
-                                {
-                                    s = ValueIsLike(sqlHead[heada] + (keyBody.Length - 2) + keyBody[index] + "", enumerable, LogicOpers[logicOper], logicOperNum, compareOper, ref keyListValueList);
-                                }
-                                else if (item.Value is JsonElement jsonElement1)
-                                {
-                                    if (jsonElement1.ValueKind is JsonValueKind.Object)
-                                    {
-
-                                        string compareOperBool = " true ";
-                                        compareOperBool = CompareBoolSwitch(compareOper);
-                                        string logicOperString = " and ";
-                                        if (logicOperNum != 0) logicOperString = LogicOpers[logicOper];
-                                        s = logicOperString + "Contains(" + sqlHead[heada] + (keyBody.Length - 2) + keyBody[index] + " , \'" + item.Value.ToString() + "\') = " + compareOperBool + " ";
-                                    }
-                                    else
-                                    {
-                                        s = ValueIsLike(sqlHead[heada] + (keyBody.Length - 2) + keyBody[index] + "", jsonElement1, LogicOpers[logicOper], logicOperNum, compareOper, ref keyListValueList);
-                                    }
-
-                                }
-                                else
-                                {
-                                    s = ValueIsLike(sqlHead[heada] + (keyBody.Length - 2) + keyBody[index] + "", item.Value, LogicOpers[logicOper], logicOperNum, compareOper, ref keyListValueList);
-                                }
-                            }
-                            else
-                            {
-                                s = ValueNotLike(sqlHead[heada] + (keyBody.Length - 2) + keyBody[index], item.Value, LogicOpers[logicOper], logicOperNum, compareOper, ref keyListValueList);
-                            }
-                            WhereString.Append(s);
-
-                            if (keyListValueList)
-                            {
-                                sql = sql.Replace("select ", "select distinct ");
-                                //sql.Clear();
-                                //sql.Append(distinctHead).Append(sqlitem);
-                            }
-                        }
-                        else
-                        {
-                            throw new BizException("数组总共深度不能超过5层", ResponseCode.PARAMS_ERROR);
-                        }
-                        heada += 1;
-
-                    }
-                    else
-                    {
-
-                        WhereString.Append(KeyNotElement(dict[item.Key], item.Key, LogicOpers[logicOper], logicOperNum, compareOper));
-
-                    }
-                    // heada += 1;
-                    logicOperNum += 1;
-                }
-                sql.Append(" where 1=1 ").Append(WhereString);
-                if (pageBool)
-                {
-                    sql.Append(" OFFSET " + offsetNum + " LIMIT " + limitNum);
-                }
-
-                ReplaceKeyWords(ref sql);
-            }
-        }
-
-        private static void GetPageNum(Dictionary<string, object> dict, ref int offsetNum, ref int limitNum, ref bool pageBool)
-        {
-            dict.TryGetValue("OFFSET", out object offset);
-            dict.Remove("OFFSET");
-            dict.TryGetValue("LIMIT", out object limit);
-            dict.Remove("LIMIT");
-            if (offset != null && limit != null)
-            {
-                pageBool = true;
-                offsetNum = int.Parse(offset.ToString());
-                limitNum = int.Parse(limit.ToString());
-            }
-        }
-
-        private static void CompareOperSwitch(string keyHead, ref string key, ref int compareOper)
-        {
-            switch (keyHead)
-            {
-                case ">":
-                    compareOper = (int)CompareOper.moreThan;
-                    key = key.Replace(">.", "");
-                    break;
-                case "<":
-                    compareOper = (int)CompareOper.lessThan;
-                    key = key.Replace("<.", "");
-                    break;
-                case "<=":
-                    compareOper = (int)CompareOper.notMoreThan;
-                    key = key.Replace("<=.", "");
-                    break;
-                case ">=":
-                    compareOper = (int)CompareOper.notLessThan;
-                    key = key.Replace(">=.", "");
-                    break;
-                case "=":
-                    compareOper = (int)CompareOper.equal;
-                    key = key.Replace("=.", "");
-                    break;
-                case "!=":
-                    compareOper = (int)CompareOper.notEqual;
-                    key = key.Replace("!=.", "");
-                    break;
-                case "$":
-                    compareOper = (int)CompareOper.like;
-                    key = key.Replace("$.", "");
-                    break;
-                case "!$":
-                    compareOper = (int)CompareOper.notLike;
-                    key = key.Replace("!$.", "");
-                    break;
-                default:
-                    compareOper = 4;
-                    break;
-            }
-        }
-
-        private static string ValueNotLike(string key, object value, string logicOperParams, int logicOperNum, int compareOperNum, ref bool keyListValueList)
-        {
-
-            string logicOper = " and ";
-            string compareOper = " = ";
-            if (compareOperNum != 4) compareOper = CompareOpers[compareOperNum];
-            if (logicOperNum != 0) logicOper = logicOperParams;
-            StringBuilder sql = new StringBuilder(logicOper + key + " in (");
-            if (value is JArray array)
-            {
-                foreach (JValue obja in array)
-                {
-                    if (obja.Value is string a)
-                    {
-                        sql.Append("\'" + a + "\',");
-                    }
-                    if (obja.Value is int b)
-                    {
-                        sql.Append(b + ",");
-                    }
-                    if (obja.Value is double c)
-                    {
-                        sql.Append(c + ",");
-                    }
-                    if (obja.Value is bool d)
-                    {
-                        sql.Append(d + ",");
-                    }
-                    if (obja.Value is long e)
-                    {
-                        sql.Append(e + ",");
-                    }
-                    if (obja.Value is DateTime f)
-                    {
-                        sql.Append(f + ",");
-                    }
-                }
-                string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                sqls += " ) ";
-                return sqls;
-            }
-            else if (value is IEnumerable enumerable && !(value is String))
-            {
-                foreach (object obja in enumerable)
-                {
-                    if (obja is string a)
-                    {
-                        sql.Append("\'" + a + "\',");
-                    }
-                    if (obja is int b)
-                    {
-                        sql.Append(" " + b + " ,");
-
-                    }
-                    if (obja is double c)
-                    {
-                        sql.Append(" " + c + " ,");
-                    }
-                    if (obja is bool d)
-                    {
-                        sql.Append(" " + d + " ,");
-
-                    }
-                    if (obja is long e)
-                    {
-                        sql.Append(" " + e + " ,");
-                    }
-                    if (obja is DateTime f)
-                    {
-                        sql.Append(" " + f + " ,");
-                    }
-                }
-                string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                sqls += ") ";
-                return sqls;
-            }
-            else if (value is JsonElement jsonElement)
-            {
-                if (jsonElement.ValueKind is JsonValueKind.Array)
-                {
-                    foreach (JsonElement obja in jsonElement.EnumerateArray().ToArray())
-                    {
-                        if (obja.ValueKind is JsonValueKind.String)
-                        {
-                            sql.Append("\'" + obja.ToString() + "\',");
-                        }
-                        if (obja.ValueKind is JsonValueKind.Number)
-                        {
-                            sql.Append(" " + int.Parse(obja.ToString()) + " ,");
-                        }
-                        if (obja.ValueKind is JsonValueKind.True)
-                        {
-                            sql.Append(" " + bool.Parse(obja.ToString()) + " ,");
-                        }
-                        if (obja.ValueKind is JsonValueKind.False)
-                        {
-                            sql.Append(" " + bool.Parse(obja.ToString()) + " ,");
-                        }
-                    }
-                }
-                else
-                {
-                    if (jsonElement.ValueKind is JsonValueKind.String)
-                    {
-                        return logicOper + key + compareOper + "\'" + value.ToString() + "\'";
-                    }
-                    if (jsonElement.ValueKind is JsonValueKind.Number)
-                    {
-                        return logicOper + key + compareOper + double.Parse(value.ToString());
-                    }
-                    if (jsonElement.ValueKind is JsonValueKind.True)
-                    {
-                        return logicOper + key + compareOper + bool.Parse(value.ToString());
-                    }
-                    if (jsonElement.ValueKind is JsonValueKind.False)
-                    {
-                        return logicOper + key + compareOper + bool.Parse(value.ToString());
-                    }
-
-                }
-
-                string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                sqls += ") ";
-                return sqls;
-            }
-            else
-            {
-                Type s = value.GetType();
-                TypeCode typeCode = Type.GetTypeCode(s);
-                if (compareOperNum == 4) keyListValueList = false;
-                return typeCode switch
-                {
-                    TypeCode.String => logicOper + key + compareOper + "\'" + value.ToString() + "\'",
-                    TypeCode.Char => logicOper + key + compareOper + "\'" + value.ToString() + "\'",
-                    TypeCode.Int32 => logicOper + key + compareOper + int.Parse(value.ToString()),
-                    TypeCode.Double => logicOper + key + compareOper + double.Parse(value.ToString()),
-                    //case TypeCode.Byte: return "and c." + key + "=" + (Byte)obj ;   
-                    TypeCode.Boolean => logicOper + key + compareOper + bool.Parse(value.ToString()),
-                    TypeCode.DateTime => logicOper + key + compareOper + (DateTime)value,
-                    TypeCode.Int64 => logicOper + key + compareOper + long.Parse(value.ToString()),
-                    _ => null,
-                };
-            }
-        }
-
-        private static string ValueIsLike(string key, object value, string logicOperParams, int logicOperNum, int compareOperNum, ref bool keyListValueList)
-        {
-            string compareOperBool = " true ";
-            compareOperBool = CompareBoolSwitch(compareOperNum);
-            string logicOper = " and ";
-            if (logicOperNum != 0) logicOper = logicOperParams;
-            StringBuilder s = new StringBuilder(logicOper + " ( Contains( ");
-
-            if (value is JArray array)
-            {
-                int aa = 0;
-                foreach (JValue obja in array)
-                {
-                    if (aa != 0) s.Append("or Contains(");
-                    if (obja.Value is string a)
-                    {
-                        s.Append(key + "," + "\'" + a + "\') = " + compareOperBool + " ");
-                    }
-                    else if (obja.Value is int b)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + b + "\' ) = " + compareOperBool + " ");
-
-                    }
-                    else if (obja.Value is double c)
-                    {
-                        s.Append("ToString( " + key + " )," + c + "\' ) = " + compareOperBool + " ");
-                    }
-                    else if (obja.Value is bool d)
-                    {
-                        s.Append("ToString( " + key + " )," + "\' " + d + "\' ) = " + compareOperBool + " ");
-
-                    }
-                    else if (obja.Value is long e)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + e + "\' ) = " + compareOperBool + " ");
-                    }
-                    else if (obja.Value is DateTime f)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + f + "\' ) = " + compareOperBool + " ");
-                    }
-                    aa++;
-                }
-            }
-            else if (value is IEnumerable enumerable && !(value is String))
-            {
-                int aa = 0;
-                foreach (object obja in enumerable)
-                {
-                    if (aa != 0) s.Append("or Contains(");
-                    if (obja is string a)
-                    {
-                        s.Append(key + "," + "\'" + a + "\') = " + compareOperBool + " ");
-                    }
-                    if (obja is int b)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + b + " \') = " + compareOperBool + " ");
-
-                    }
-                    if (obja is double c)
-                    {
-                        s.Append("ToString( " + key + " )," + "\' " + c + " \') = " + compareOperBool + " ");
-                    }
-                    if (obja is bool d)
-                    {
-                        s.Append("ToString( " + key + " )," + "\' " + d + "\' ) = " + compareOperBool + " ");
-
-                    }
-                    if (obja is long e)
-                    {
-                        s.Append("ToString( " + key + " )," + "\' " + e + " \') = " + compareOperBool + " ");
-                    }
-                    if (obja is DateTime f)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + f + " \') = " + compareOperBool + " ");
-                    }
-                    aa++;
-                }
-
-            }
-            else if (value is JsonValueKind.Array && value is JsonElement jsonElement)
-            {
-                int aa = 0;
-                //jsonElement.EnumerateArray().ToArray();
-                foreach (JsonElement obja in jsonElement.EnumerateArray().ToArray())
-                {
-                    if (aa != 0) s.Append("or Contains(");
-                    if (obja.ValueKind is JsonValueKind.String)
-                    {
-                        s.Append(key + "," + "\'" + obja.ToString() + "\') = " + compareOperBool + " ");
-                    }
-                    if (obja.ValueKind is JsonValueKind.Number)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + obja.ToString() + " \') = " + compareOperBool + " ");
-                    }
-                    if (obja.ValueKind is JsonValueKind.True)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + obja.ToString() + " \') = " + compareOperBool + " ");
-                    }
-                    if (obja.ValueKind is JsonValueKind.False)
-                    {
-                        s.Append("ToString( " + key + " )," + " \'" + obja.ToString() + " \') = " + compareOperBool + " ");
-                    }
-                    aa++;
-                }
-            }
-            else
-            {
-                Type stype = value.GetType();
-                TypeCode typeCode = Type.GetTypeCode(stype);
-                keyListValueList = false;
-                string sql = "";
-                switch (typeCode)
-                {
-                    case TypeCode.String:
-                        sql = logicOper + "Contains( " + key + " , \'" + value.ToString() + "\') = " + compareOperBool + " ";
-                        break;
-                    case TypeCode.Char:
-                        sql = logicOper + "Contains( " + key + " , \'" + value.ToString() + "\') = " + compareOperBool + " ";
-                        break;
-                    case TypeCode.Int16:
-                    case TypeCode.Int32:
-                    case TypeCode.Int64:
-                    case TypeCode.Double:
-                    case TypeCode.Boolean:
-                    case TypeCode.DateTime:
-                    case TypeCode.Object:
-                        sql = logicOper + "Contains(  ToString( " + key + " ), \'" + value.ToString() + "\' ) = " + compareOperBool + " ";
-                        break;
-
-                    default:
-                        break;
-                }
-
-                return sql;
-            }
-            s.Append(" )");
-            return s.ToString();
-        }
-
-        private static string CompareBoolSwitch(int compareOperNum)
-        {
-            return compareOperNum switch
-            {
-                6 => " true ",
-                7 => " false ",
-                _ => " true ",
-            };
-
-        }
-
-        private static string KeyNotElement(object value, string key, string logicOperParams, int logicOperNum, int compareOperNum)
-        {
-            string compareOperBool = " true ";
-            compareOperBool = CompareBoolSwitch(compareOperNum);
-            string logicOper = " and ";
-            int compareOper = 4;
-            if (logicOperNum != 0) logicOper = logicOperParams;
-            if (key.EndsWith(".&"))
-            {
-                key = key.Replace(".&", "");
-            }
-            else if (key.EndsWith(".|"))
-            {
-                key = key.Replace(".|", "");
-            }
-            string[] keyHead = key.Split(".");
-            CompareOperSwitch(keyHead[0], ref key, ref compareOper);
-
-            if (compareOper == 6 || compareOper == 7)
-            {
-                StringBuilder sql = new StringBuilder(logicOper + " ( Contains( ");
-                if (value is JArray jarray)
-                {
-                    int aa = 0;
-                    foreach (JValue obja in jarray)
-                    {
-                        if (aa != 0) sql.Append("or Contains(");
-                        if (obja.Value is string a)
-                        {
-                            sql.Append(" c." + key + ",\'" + a + "\')= " + compareOperBool + "  ");
-                        }
-                        if (obja.Value is int b)
-                        {
-                            sql.Append(" ToString( c." + key + " ), \'" + b + " \')= " + compareOperBool + "  ");
-                        }
-                        if (obja.Value is double c)
-                        {
-                            sql.Append(" ToString( c." + key + " ), \'" + c + " \') = " + compareOperBool + "  ");
-                        }
-                        if (obja.Value is bool d)
-                        {
-                            sql.Append(" ToString( c." + key + " ), \'" + d + "\' ) = " + compareOperBool + "  ");
-
-                        }
-                        if (obja.Value is long e)
-                        {
-                            sql.Append(" ToString( c." + key + " ), \'" + e + " \') = " + compareOperBool + "  ");
-                        }
-                        if (obja.Value is DateTime f)
-                        {
-                            sql.Append(" ToString( c." + key + " ), \'" + f + " \') = " + compareOperBool + "  ");
-                        }
-                        aa++;
-                    }
-                }
-                else if (value is IEnumerable enumerable && !(value is String))
-                {
-                    int aa = 0;
-                    foreach (object obja in enumerable)
-                    {
-                        if (aa != 0) sql.Append("or Contains(");
-                        if (obja is string a)
-                        {
-                            sql.Append(" c." + key + "," + "\'" + a + "\') = " + compareOperBool + "  ");
-                        }
-                        if (obja is int b)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + "\' " + b + "\' ) = " + compareOperBool + "  ");
-                        }
-                        if (obja is double c)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + "\' " + c + "\' ) = " + compareOperBool + "  ");
-                        }
-                        if (obja is bool d)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + "\' " + d + " \') = " + compareOperBool + "  ");
-                        }
-                        if (obja is long e)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + " \'" + e + "\' ) = " + compareOperBool + "  ");
-                        }
-                        if (obja is DateTime f)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + " \'" + f + "\') = " + compareOperBool + "  ");
-                        }
-                        aa++;
-                    }
-                }
-                else if (value is JsonElement jsonElement && jsonElement.ValueKind! is JsonValueKind.Array)
-                {
-                    int aa = 0;
-                    foreach (JsonElement obja in jsonElement.EnumerateArray().ToArray())
-                    {
-                        if (aa != 0) sql.Append("or Contains(");
-                        if (obja.ValueKind is JsonValueKind.String)
-                        {
-                            sql.Append(" c." + key + "," + "\'" + obja.ToString() + "\') = " + compareOperBool + "  ");
-                        }
-                        if (obja.ValueKind is JsonValueKind.Number)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + " " + int.Parse(obja.ToString()) + " ) = " + compareOperBool + "  ");
-                        }
-                        if (obja.ValueKind is JsonValueKind.True)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + " " + bool.Parse(obja.ToString()) + " ) = " + compareOperBool + "  ");
-                        }
-                        if (obja.ValueKind is JsonValueKind.False)
-                        {
-                            sql.Append(" ToString( c." + key + " )," + " " + bool.Parse(obja.ToString()) + " ) = " + compareOperBool + "  ");
-                        }
-                        aa++;
-                    }
-                }
-                else
-                {
-                    Type s = value.GetType();
-                    TypeCode typeCode = Type.GetTypeCode(s);
-
-                    string sql1 = "";
-                    switch (typeCode)
-                    {
-                        case TypeCode.String:
-                            sql1 = logicOper + "Contains(  c." + key + " , \'" + value.ToString() + "\') = " + compareOperBool + " ";
-                            break;
-                        case TypeCode.Char:
-                            sql1 = logicOper + "Contains( c." + key + " , \'" + value.ToString() + "\') = " + compareOperBool + " ";
-                            break;
-                        case TypeCode.Int16:
-                        case TypeCode.Int32:
-                        case TypeCode.Int64:
-                        case TypeCode.Double:
-                        case TypeCode.Boolean:
-                        case TypeCode.DateTime:
-                        case TypeCode.Object:
-                            sql1 = logicOper + "Contains(  ToString(  c." + key + "  ), \'" + value.ToString() + "\' ) = " + compareOperBool + " ";
-                            break;
-
-                        default:
-                            break;
-                    }
-
-                    return sql1;
-                }
-
-                sql.Append(")");
-                return sql.ToString();
-            }
-            else
-            {
-                StringBuilder sql = new StringBuilder(logicOper + " c." + key + " in (");
-                if (value is JArray array)
-                {
-
-                    foreach (JValue obja in array)
-                    {
-                        if (obja.Value is string a)
-                        {
-                            sql.Append("\'" + a + "\',");
-                        }
-                        if (obja.Value is int b)
-                        {
-                            sql.Append(b + ",");
-                        }
-                        if (obja.Value is double c)
-                        {
-                            sql.Append(c + ",");
-                        }
-                        if (obja.Value is bool d)
-                        {
-                            sql.Append(d + ",");
-                        }
-                        if (obja.Value is long e)
-                        {
-                            sql.Append(e + ",");
-                        }
-                        if (obja.Value is DateTime f)
-                        {
-                            sql.Append(f + ",");
-                        }
-                    }
-                    string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                    sqls += " ) ";
-                    return sqls;
-                }
-                else if (value is IEnumerable enumerable && !(value is String))
-                {
-                    foreach (object obja in enumerable)
-                    {
-                        if (obja is string a)
-                        {
-                            sql.Append("\'" + a + "\',");
-                        }
-                        if (obja is int b)
-                        {
-                            sql.Append(" " + b + " ,");
-                        }
-                        if (obja is double c)
-                        {
-                            sql.Append(" " + c + " ,");
-                        }
-                        if (obja is bool d)
-                        {
-                            sql.Append(" " + d + " ,");
-
-                        }
-                        if (obja is long e)
-                        {
-                            sql.Append(" " + e + " ,");
-                        }
-                        if (obja is DateTime f)
-                        {
-                            sql.Append(" " + f + " ,");
-                        }
-                    }
-                    string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                    sqls += ") ";
-                    return sqls;
-                }
-                else if (value is JsonElement jsonElement)
-                {
-                    if (jsonElement.ValueKind is JsonValueKind.Array)
-                    {
-                        foreach (JsonElement obja in jsonElement.EnumerateArray().ToArray())
-                        {
-                            if (obja.ValueKind is JsonValueKind.String)
-                            {
-                                sql.Append("\'" + obja.ToString() + "\',");
-                            }
-                            if (obja.ValueKind is JsonValueKind.Number)
-                            {
-                                sql.Append(" " + int.Parse(obja.ToString()) + " ,");
-                            }
-                            if (obja.ValueKind is JsonValueKind.True)
-                            {
-                                sql.Append(" " + bool.Parse(obja.ToString()) + " ,");
-                            }
-                            if (obja.ValueKind is JsonValueKind.False)
-                            {
-                                sql.Append(" " + bool.Parse(obja.ToString()) + " ,");
-                            }
-                        }
-                    }
-                    else
-                    {
-                        if (jsonElement.ValueKind is JsonValueKind.String)
-                        {
-                            return logicOper + " c." + key + CompareOpers[compareOperNum] + "\'" + value.ToString() + "\'";
-                        }
-                        if (jsonElement.ValueKind is JsonValueKind.Number)
-                        {
-                            return logicOper + "  c." + key + CompareOpers[compareOperNum] + double.Parse(value.ToString());
-                        }
-                        if (jsonElement.ValueKind is JsonValueKind.True)
-                        {
-                            return logicOper + "  c." + key + CompareOpers[compareOperNum] + bool.Parse(value.ToString());
-                        }
-                        if (jsonElement.ValueKind is JsonValueKind.False)
-                        {
-                            return logicOper + "  c." + key + CompareOpers[compareOperNum] + bool.Parse(value.ToString());
-                        }
-
-                    }
-
-                    string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                    sqls += ") ";
-                    return sqls;
-                }
-                else
-                {
-                    Type s = value.GetType();
-                    TypeCode typeCode = Type.GetTypeCode(s);
-
-                    return typeCode switch
-                    {
-                        TypeCode.String => logicOper + " c." + key + CompareOpers[compareOperNum] + "\'" + value.ToString() + "\'",
-                        TypeCode.Char => logicOper + " c." + key + CompareOpers[compareOperNum] + "\'" + value.ToString() + "\'",
-                        TypeCode.Int32 => logicOper + "  c." + key + CompareOpers[compareOperNum] + int.Parse(value.ToString()),
-                        TypeCode.Double => logicOper + "  c." + key + CompareOpers[compareOperNum] + double.Parse(value.ToString()),
-                        //case TypeCode.Byte: return "and c." + key + "=" + (Byte)obj ;   
-                        TypeCode.Boolean => logicOper + "  c." + key + CompareOpers[compareOperNum] + bool.Parse(value.ToString()),
-                        TypeCode.DateTime => logicOper + "  c." + key + CompareOpers[compareOperNum] + (DateTime)value,
-                        TypeCode.Int64 => logicOper + "  c." + key + CompareOpers[compareOperNum] + long.Parse(value.ToString()),
-                        _ => null,
-                    };
-                }
-            }
-        }
-
-
-        public enum LogicOper : int
-        {
-            and = 0, or = 1
-        }
-        public enum CompareOper : int
-        {
-            moreThan = 0, lessThan = 1, notMoreThan = 2, notLessThan = 3, equal = 4, notEqual = 5, like = 6, notLike = 7, IN = 8
-        }
-
-    }
-}

+ 0 - 851
TEAMModelOS.SDK/Module/AzureCosmosDB/Implements/AzureCosmosDBRepository.cs

@@ -1,851 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using System.Linq;
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Interfaces;
-using Microsoft.Azure.Documents.Client;
-using Microsoft.Azure.Documents;
-using TEAMModelOS.SDK.Helper.Security.AESCrypt;
-using TEAMModelOS.SDK.Context.Exception;
-using Microsoft.Azure.Documents.Linq;
-using TEAMModelOS.SDK.Helper.Query.LinqHelper;
-using System.Reflection;
-using Microsoft.Azure.Cosmos;
-using Microsoft.Azure.CosmosDB.BulkExecutor;
-using Microsoft.Azure.CosmosDB.BulkExecutor.BulkImport;
-using System.Threading;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using Microsoft.Azure.CosmosDB.BulkExecutor.BulkUpdate;
-using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using Microsoft.Azure.CosmosDB.BulkExecutor.BulkDelete;
-using TEAMModelOS.SDK.Context.Attributes.Azure;
-using System.Text;
-using TEAMModelOS.SDK.Helper.Common.ReflectorExtensions;
-using Microsoft.AspNetCore.Hosting;
-using System.Collections.Concurrent;
-using DataType = Microsoft.Azure.Documents.DataType;
-using RequestOptions = Microsoft.Azure.Documents.Client.RequestOptions;
-using PartitionKey = Microsoft.Azure.Documents.PartitionKey;
-using Newtonsoft.Json.Linq;
-using TEAMModelOS.SDK.Helper.Common.LogHelper;
-using System.Text.Json;
-using System.Collections;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
-{ /// <summary>
-  /// sdk 文档https://github.com/Azure/azure-cosmos-dotnet-v2/tree/master/samples
-  /// https://github.com/Azure/azure-cosmos-dotnet-v2/blob/530c8d9cf7c99df7300246da05206c57ce654233/samples/code-samples/DatabaseManagement/Program.cs#L72-L121
-  /// </summary>
-    public class AzureCosmosDBRepository : IAzureCosmosDBRepository
-    {
-        /// <summary>
-        /// sdk 文档https://github.com/Azure/azure-cosmos-dotnet-v2/tree/master/samples
-        /// https://github.com/Azure/azure-cosmos-dotnet-v2/blob/530c8d9cf7c99df7300246da05206c57ce654233/samples/code-samples/DatabaseManagement/Program.cs#L72-L121
-        /// </summary>
-
-
-        private DocumentClient CosmosClient { get; set; }
-        /// <summary>
-        /// 线程安全的dict类型
-        /// </summary>
-        private ConcurrentDictionary<string, DocumentCollection> DocumentCollectionDict { get; set; } = new ConcurrentDictionary<string, DocumentCollection>();
-
-        // private DocumentCollection CosmosCollection { get; set; }
-        private string Database { get; set; }
-        private int CollectionThroughput { get; set; }
-        public AzureCosmosDBRepository(AzureCosmosDBOptions options)
-        {
-            try
-            {
-                if (!string.IsNullOrEmpty(options.ConnectionString))
-                {
-                    CosmosClient = CosmosDBClientSingleton.getInstance(options.ConnectionString, options.ConnectionKey).GetCosmosDBClient();
-                }
-                else
-                {
-                    throw new BizException("请设置正确的AzureCosmosDB数据库配置信息!");
-                }
-                Database = options.Database;
-                CollectionThroughput = options.CollectionThroughput;
-                CosmosClient.CreateDatabaseIfNotExistsAsync(new Microsoft.Azure.Documents.Database { Id = Database });
-                // _connectionString = options.ConnectionString;
-                // CosmosSerializer
-
-                //获取数据库所有的表
-                Microsoft.Azure.Documents.Client.FeedResponse<DocumentCollection> collections = CosmosClient.ReadDocumentCollectionFeedAsync(UriFactory.CreateDatabaseUri(Database)).GetAwaiter().GetResult();
-                foreach (IGrouping<string, DocumentCollection> group in collections.GroupBy(c => c.Id))
-                {
-                    DocumentCollectionDict.TryAdd(group.Key, group.First());
-                }
-                //collections
-                List<Type> types = ReflectorExtensions.GetAllTypeAsAttribute<CosmosDBAttribute>(options.ScanModel);
-                foreach (Type type in types)
-                {
-                    string PartitionKey = GetPartitionKey(type);
-                    string CollectionName = "";
-                    int RU = 0;
-                    IEnumerable<CosmosDBAttribute> attributes = type.GetCustomAttributes<CosmosDBAttribute>(true);
-                    if (!string.IsNullOrEmpty(attributes.First<CosmosDBAttribute>().Name))
-                    {
-                        CollectionName = attributes.First<CosmosDBAttribute>().Name;
-                    }
-                    else
-                    {
-                        CollectionName = type.Name;
-                    }
-                    if (attributes.First<CosmosDBAttribute>().RU > 400)
-                    {
-                        RU = attributes.First<CosmosDBAttribute>().RU;
-                    }
-                    else
-                    {
-                        RU = options.CollectionThroughput;
-                    }
-                    //如果表存在于数据则检查RU是否变动,如果不存在则执行创建DocumentCollection
-                    if (DocumentCollectionDict.TryGetValue(CollectionName, out DocumentCollection collection))
-                    {
-                        Offer offer = CosmosClient.CreateOfferQuery().Where(o => o.ResourceLink == collection.SelfLink).AsEnumerable().Single();
-                        OfferV2 offerV2 = (OfferV2)offer;
-                        //更新RU
-                        if (offerV2.Content.OfferThroughput < RU)
-                        {
-                            CosmosClient.ReplaceOfferAsync(new OfferV2(offer, RU));
-                        }
-                    }
-                    else
-                    {
-                        DocumentCollection collectionDefinition = new DocumentCollection { Id = CollectionName };
-                        collectionDefinition.IndexingPolicy = new Microsoft.Azure.Documents.IndexingPolicy(new RangeIndex(DataType.String) { Precision = -1 });
-
-                        // collectionDefinition.PartitionKey = new PartitionKeyDefinition {  Paths = new System.Collections.ObjectModel.Collection<string>() };
-                        if (!string.IsNullOrEmpty(PartitionKey))
-                        {
-                            collectionDefinition.PartitionKey.Paths.Add("/" + PartitionKey);
-                        }
-                        // CosmosCollection = await this.CosmosClient.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(Database), collectionDefinition);
-                        if (RU > CollectionThroughput)
-                        {
-                            CollectionThroughput = RU;
-                        }
-                        DocumentCollection DocumentCollection = CosmosClient.CreateDocumentCollectionIfNotExistsAsync(
-                            UriFactory.CreateDatabaseUri(Database), collectionDefinition, new Microsoft.Azure.Documents.Client.RequestOptions { OfferThroughput = CollectionThroughput }).GetAwaiter().GetResult();
-                        DocumentCollectionDict.TryAdd(CollectionName, DocumentCollection);
-                    }
-                }
-            }
-            catch (DocumentClientException de)
-            {
-                Exception baseException = de.GetBaseException();
-                //Console.WriteLine("{0} error occurred: {1}, Message: {2}", de.StatusCode, de.Message, baseException.Message);
-            }
-            catch (Exception e)
-            {
-                Exception baseException = e.GetBaseException();
-                //Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
-            }
-            finally
-            {
-                //  Console.WriteLine("End of demo, press any key to exit.");
-                //  Console.ReadKey();
-            }
-        }
-
-        private async Task<DocumentCollection> InitializeCollection<T>()
-        {
-            Type type = typeof(T);
-            string partitionKey = GetPartitionKey<T>();
-            string CollectionName;
-            IEnumerable<CosmosDBAttribute> attributes = type.GetCustomAttributes<CosmosDBAttribute>(true);
-            if (!string.IsNullOrEmpty(attributes.First<CosmosDBAttribute>().Name))
-            {
-                CollectionName = attributes.First<CosmosDBAttribute>().Name;
-            }
-            else
-            {
-                CollectionName = type.Name;
-            }
-            return await InitializeCollection(CollectionName, partitionKey);
-        }
-
-        private async Task<DocumentCollection> InitializeCollection(string CollectionName, string PartitionKey)
-        {
-            /////内存中已经存在这个表则直接返回
-            if (DocumentCollectionDict.TryGetValue(CollectionName, out DocumentCollection DocumentCollection))
-            {
-                return DocumentCollection;
-            }///如果没有则尝试默认创建
-            else
-            {
-                DocumentCollection documentCollection = new DocumentCollection { Id = CollectionName };
-                documentCollection.IndexingPolicy = new Microsoft.Azure.Documents.IndexingPolicy(new RangeIndex(DataType.String) { Precision = -1 });
-
-                // collectionDefinition.PartitionKey = new PartitionKeyDefinition {  Paths = new System.Collections.ObjectModel.Collection<string>() };
-                if (!string.IsNullOrEmpty(PartitionKey))
-                {
-                    documentCollection.PartitionKey.Paths.Add("/" + PartitionKey);
-                }
-                // CosmosCollection = await this.CosmosClient.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(Database), collectionDefinition);
-                documentCollection =   await this.CosmosClient.CreateDocumentCollectionIfNotExistsAsync(
-                       UriFactory.CreateDatabaseUri(Database), documentCollection, new RequestOptions { OfferThroughput = CollectionThroughput });
-                DocumentCollectionDict.TryAdd(CollectionName, documentCollection);
-                return documentCollection;
-            }
-        }
-
-        private string GetPartitionKey<T>()
-        {
-            Type type = typeof(T);
-            return GetPartitionKey(type);
-        }
-        private string GetPartitionKey(Type type)
-        {
-            PropertyInfo[] properties = type.GetProperties();
-            List<PropertyInfo> attrProperties = new List<PropertyInfo>();
-            foreach (PropertyInfo property in properties)
-            {
-                if (property.Name.Equals("PartitionKey"))
-                {
-                    attrProperties.Add(property);
-                    break;
-                }
-                object[] attributes = property.GetCustomAttributes(true);
-                foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
-                {
-                    if (attribute is PartitionKeyAttribute)
-                    {
-                        attrProperties.Add(property);
-                    }
-                }
-            }
-            if (attrProperties.Count <= 0)
-            {
-                throw new BizException(type.Name +"has no PartitionKey !!!!!!");
-            }
-            else
-            {
-                if (attrProperties.Count == 1)
-                {
-                    return attrProperties[0].Name;
-                }
-                else { throw new BizException("PartitionKey can only be single!"); }
-            }
-        }
-        public async Task<T> Save<T>(T entity)  //where T : object, new()
-        {
-            try
-            {
-                Type t = typeof(T);
-              DocumentCollection collection=  await InitializeCollection<T>();
-                ResourceResponse<Document> doc =
-                    await CosmosClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(Database, collection.Id), entity);
-                //Console.WriteLine(doc.ActivityId);
-                return entity;
-            }
-            catch (Exception e)
-            {
-                throw new BizException(e.Message);
-            }
-        }
-
-        public async Task<T> Update<T>(T entity)
-        {
-            Type t = typeof(T);
-            DocumentCollection collection = await InitializeCollection<T>();
-            ResourceResponse<Document> doc =
-                await CosmosClient.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(Database, collection.Id), entity);
-            return entity;
-        }
-        public async Task<string> ReplaceObject<T>(T entity, string key)
-        {
-            Type t = typeof(T);
-            DocumentCollection collection = await InitializeCollection<T>();
-            try
-            {
-                ResourceResponse<Document> doc =
-                await CosmosClient.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(Database,collection.Id, key), entity);
-                return key;
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("{0} Exception caught.", e);
-                //return false;
-            }
-            return null;
-
-        }
-
-        public async Task<string> ReplaceObject<T>(T entity, string key, string partitionKey)
-        {
-            Type t = typeof(T);
-            DocumentCollection collection = await InitializeCollection<T>();
-            try
-            {
-                ResourceResponse<Document> doc =
-                await CosmosClient.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(Database,collection.Id, key),
-                entity,
-                new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });
-                return key;
-            }
-            catch (Exception e)
-            {
-                throw new BizException(e.Message);
-                //Console.WriteLine("{0} Exception caught.", e);
-                //return false;
-            }
-        }
-
-        public async Task<List<T>> FindAll<T>()
-        {
-            Type t = typeof(T);
-            Boolean open = true;
-            List<T> objs = new List<T>();
-
-            DocumentCollection collection =  await InitializeCollection<T>();
-            //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = open };
-            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database,collection.Id), queryOptions).AsDocumentQuery();
-            while (query.HasMoreResults)
-            {
-                foreach (T obj in await query.ExecuteNextAsync())
-                {
-                    objs.Add(obj);
-                }
-            }
-            return objs;
-            //return CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, t.Name),sql);
-
-        }
-
-        public async Task<List<T>> FindLinq<T>(Func<IQueryable<object>, object> singleOrDefault)
-        {
-            Type t = typeof(T);
-
-            List<T> objs = new List<T>();
-            DocumentCollection collection = await InitializeCollection<T>();
-            //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 };
-            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, collection.Id), queryOptions);
-
-            //  query.Where();
-            return objs;
-            //return CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, t.Name),sql);
-
-        }
-
-        public async Task<List<T>> FindSQL<T>(string sql)
-        {
-            Type t = typeof(T);
-            //List<T> objs = new List<T>();
-            DocumentCollection collection =  await InitializeCollection<T>();
-            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database,collection.Id), sql);
-            //foreach (var item in query)
-            //{
-            //    objs.Add(item);
-            //}
-            return query.ToList<T>();
-
-        }
-
-        public async Task<List<T>> FindSQL<T>(string sql, bool IsPk)
-        {
-            Type t = typeof(T);
-            //List<T> objs = new List<T>();
-            // Boolean open = IsPk;
-            DocumentCollection collection = await InitializeCollection<T>();
-            //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = IsPk };
-            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, collection.Id), sql, queryOptions);
-            //foreach (var item in query)
-            //{
-            //    objs.Add(item);
-            //}
-            return query.ToList<T>();
-
-        }
-
-
-
-        public async Task<List<T>> FindByParams<T>(Dictionary<string, object> dict)
-        {
-            DocumentCollection collection =  await InitializeCollection<T>();
-            Type t = typeof(T);
-            Boolean open = true;
-            List<Filter> filters = new List<Filter>();
-
-            string PKname = "";
-            PropertyInfo[] properties = t.GetProperties();
-            foreach (PropertyInfo property in properties)
-            {
-                object[] attributes = property.GetCustomAttributes(true);
-                foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
-                {
-                    if (attribute is PartitionKeyAttribute)
-                    {
-                        PKname = property.Name;
-                        break;
-                    }
-                }
-            }
-            foreach (string key in dict.Keys)
-            {
-                //if (t.Name.Equals(key)) {
-                //    open = false;
-                //}
-
-                if (PKname.Equals(key))
-                {
-                    open = false;
-                }
-                filters.Add(new Filter { Contrast = "and", Key = key, Value = dict[key] != null ? dict[key].ToString() : throw new Exception("参数值不能为null") });
-            }
-
-
-            //List<T> objs = new List<T>();
-            await InitializeCollection<T>();
-            //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = open };
-            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, collection.Id), queryOptions);
-            List<T> list = DynamicLinq.GenerateFilter<T>(query, filters).ToList();
-            return list;
-            //return CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, t.Name),sql);
-
-        }
-        public async Task<string> DeleteAsync<T>(string id)
-        {
-            Type t = typeof(T);
-            DocumentCollection collection = await InitializeCollection<T>();
-            ResourceResponse<Document> doc =
-                await CosmosClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Database,collection.Id, id));
-            //Console.WriteLine(doc.ActivityId);
-            return id;
-        }
-        public async Task<T> DeleteAsync<T>(T entity)
-        {
-            DocumentCollection collection =  await InitializeCollection<T>();
-            Type t = typeof(T);
-            string PartitionKey = GetPartitionKey<T>();
-            if (!string.IsNullOrEmpty(PartitionKey))
-            {
-                string pkValue = entity.GetType().GetProperty(PartitionKey).GetValue(entity).ToString();
-                string idValue = entity.GetType().GetProperty("id").GetValue(entity).ToString();
-                ResourceResponse<Document> doc =
-              await CosmosClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Database, collection.Id, idValue), new RequestOptions { PartitionKey = new PartitionKey(pkValue) });
-            }
-            else
-            {
-                string idValue = entity.GetType().GetProperty("id").GetValue(entity).ToString();
-                ResourceResponse<Document> doc =
-                await CosmosClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Database, collection.Id, idValue));
-            }
-            //log4net 日志記錄
-            string uuidKey = Guid.NewGuid().ToString();
-            string logkey = "【" + uuidKey + "】";
-            LogHelper.Info(this,
-                           logkey
-                           +"【删除】"
-                           + "【表】"
-                           + t.Name
-                           + "【数据】"
-                           + entity.ToJson()
-                           + logkey);
-            
-            
-
-            //Console.WriteLine(doc.ActivityId);
-            return entity;
-
-        }
-        public async Task<string> DeleteAsync<T>(string id, string partitionKey)
-        {
-            Type t = typeof(T);
-
-            DocumentCollection collection = await InitializeCollection<T>();
-            ResourceResponse<Document> doc =
-                await CosmosClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Database, collection.Id, id), new RequestOptions { PartitionKey = new PartitionKey(partitionKey) });
-            //Console.WriteLine(doc.ActivityId);
-            return id;
-
-        }
-
-        public async Task<List<T>> SaveAll<T>(List<T> enyites)
-        {
-            DocumentCollection dataCollection = await InitializeCollection<T>();
-            // Set retry options high for initialization (default values).
-            CosmosClient.ConnectionPolicy.RetryOptions.MaxRetryWaitTimeInSeconds = 30;
-            CosmosClient.ConnectionPolicy.RetryOptions.MaxRetryAttemptsOnThrottledRequests = 9;
-            IBulkExecutor bulkExecutor = new BulkExecutor(CosmosClient, dataCollection);
-            await bulkExecutor.InitializeAsync();
-            // Set retries to 0 to pass control to bulk executor.
-            CosmosClient.ConnectionPolicy.RetryOptions.MaxRetryWaitTimeInSeconds = 0;
-            CosmosClient.ConnectionPolicy.RetryOptions.MaxRetryAttemptsOnThrottledRequests = 0;
-            BulkImportResponse bulkImportResponse = null;
-            long totalNumberOfDocumentsInserted = 0;
-            double totalRequestUnitsConsumed = 0;
-            double totalTimeTakenSec = 0;
-            var tokenSource = new CancellationTokenSource();
-            var token = tokenSource.Token;
-            int pageSize = 50;
-            int pages = (int)Math.Ceiling((double)enyites.Count / pageSize);
-
-            for (int i = 0; i < pages; i++)
-            {
-                List<string> documentsToImportInBatch = new List<string>();
-                List<T> lists = enyites.Skip((i) * pageSize).Take(pageSize).ToList();
-                for (int j = 0; j < lists.Count; j++)
-                {
-                    documentsToImportInBatch.Add(lists[j].ToJson());
-                }
-                var tasks = new List<Task>
-                { Task.Run(async () =>
-                    {
-                        do
-                        {
-                            bulkImportResponse = await bulkExecutor.BulkImportAsync(
-                                documents: documentsToImportInBatch,
-                                enableUpsert: true,
-                                disableAutomaticIdGeneration: true,
-                                maxConcurrencyPerPartitionKeyRange: null,
-                                maxInMemorySortingBatchSize: null,
-                                cancellationToken: token);
-                            
-                        } while (bulkImportResponse.NumberOfDocumentsImported < documentsToImportInBatch.Count);
-                        totalNumberOfDocumentsInserted += bulkImportResponse.NumberOfDocumentsImported;
-                        totalRequestUnitsConsumed += bulkImportResponse.TotalRequestUnitsConsumed;
-                        totalTimeTakenSec += bulkImportResponse.TotalTimeTaken.TotalSeconds;
-                    },
-                token)
-                };
-                await Task.WhenAll(tasks);
-            }
-            return enyites;
-        }
-        public async Task<List<T>> UpdateAll<T>(Dictionary<string, object> dict, Dictionary<string, object> updateFilters, List<string> deleteKeys = null)
-        {
-
-            DocumentCollection dataCollection = await InitializeCollection<T>();
-            IBulkExecutor bulkExecutor = new BulkExecutor(CosmosClient, dataCollection);
-            await bulkExecutor.InitializeAsync();
-            BulkUpdateResponse bulkUpdateResponse = null;
-            long totalNumberOfDocumentsUpdated = 0;
-
-            double totalRequestUnitsConsumed = 0;
-            double totalTimeTakenSec = 0;
-
-            var tokenSource = new CancellationTokenSource();
-            var token = tokenSource.Token;
-            // Generate update operations.
-            List<UpdateOperation> updateOperations = new List<UpdateOperation>();
-            // Unset the description field.
-            if (null != updateFilters && updateFilters.Count > 0)
-            {
-                var keys = updateFilters.Keys;
-                foreach (string key in keys)
-                {
-                    // updateOperations.Add(new SetUpdateOperation<string>())
-                    if (updateFilters[key] != null && !string.IsNullOrEmpty(updateFilters[key].ToString()))
-                    {
-                        updateOperations.Add(SwitchType(key, updateFilters[key]));
-                    }
-                }
-            }
-            if (deleteKeys.IsNotEmpty())
-            {
-                foreach (string key in deleteKeys)
-                {
-                    updateOperations.Add(new UnsetUpdateOperation(key));
-                }
-            }
-            List<T> list = await FindByParams<T>(dict);
-            int pageSize = 100;
-            int pages = (int)Math.Ceiling((double)list.Count / pageSize);
-            string partitionKey = "/" + GetPartitionKey<T>();
-            Type type = typeof(T);
-            for (int i = 0; i < pages; i++)
-            {
-                List<UpdateItem> updateItemsInBatch = new List<UpdateItem>();
-                List<T> lists = list.Skip((i) * pageSize).Take(pageSize).ToList();
-                for (int j = 0; j < lists.Count; j++)
-                {
-                    string partitionKeyValue = lists[j].GetType().GetProperty(partitionKey).GetValue(lists[j]) + "";
-                    string id = lists[j].GetType().GetProperty("id").GetValue(lists[j]) + "";
-                    updateItemsInBatch.Add(new UpdateItem(id, partitionKeyValue, updateOperations));
-                }
-                var tasks = new List<Task>
-                { Task.Run(async () =>
-                    {
-                        do
-                        {
-                            //try
-                            //{
-                            bulkUpdateResponse = await bulkExecutor.BulkUpdateAsync(
-                                updateItems: updateItemsInBatch,
-                                maxConcurrencyPerPartitionKeyRange: null,
-                                cancellationToken: token);
-                            //}
-                            //catch (DocumentClientException de)
-                            //{
-                            //    break;
-                            //}
-                            //catch (Exception e)
-                            //{
-                            //    break;
-                            //}
-                        } while (bulkUpdateResponse.NumberOfDocumentsUpdated < updateItemsInBatch.Count);
-                        totalNumberOfDocumentsUpdated += bulkUpdateResponse.NumberOfDocumentsUpdated;
-                        totalRequestUnitsConsumed += bulkUpdateResponse.TotalRequestUnitsConsumed;
-                        totalTimeTakenSec += bulkUpdateResponse.TotalTimeTaken.TotalSeconds;
-                    },
-                token)
-                };
-                await Task.WhenAll(tasks);
-            }
-            return list;
-        }
-        public async Task<List<T>> DeleteAll<T>(Dictionary<string, object> dict)
-        {
-            DocumentCollection dataCollection = await InitializeCollection<T>();
-            List<T> list = await FindByDict<T>(dict);
-            List<Tuple<string, string>> pkIdTuplesToDelete = new List<Tuple<string, string>>();
-            string PartitionKey = GetPartitionKey<T>();
-            if (list.IsNotEmpty())
-            {
-                foreach (T t in list)
-                {
-                    
-                    string pkValue = t.GetType().GetProperty(PartitionKey).GetValue(t).ToString();
-                    string id = t.GetType().GetProperty("id").GetValue(t) + "";
-                    pkIdTuplesToDelete.Add(new Tuple<string, string>(pkValue, id));
-
-                    //log4net 日志記錄
-                    string uuidKey = Guid.NewGuid().ToString();
-                    string logkey = "【" + uuidKey + "】";
-                    LogHelper.Info(this,
-                                   logkey
-                                   + "【删除】"
-                                   + "【表】"
-                                   + t.GetType()
-                                   + "【数据】"
-                                   + t.ToJson()
-                                   + logkey);
-                }
-            }
-            else
-            {
-                return list;
-            }
-            long totalNumberOfDocumentsDeleted = 0;
-            double totalRequestUnitsConsumed = 0;
-            double totalTimeTakenSec = 0;
-            BulkDeleteResponse bulkDeleteResponse = null;
-
-            BulkExecutor bulkExecutor = new BulkExecutor(CosmosClient, dataCollection);
-            await bulkExecutor.InitializeAsync();
-
-            try
-            {
-                bulkDeleteResponse = await bulkExecutor.BulkDeleteAsync(pkIdTuplesToDelete);
-                totalNumberOfDocumentsDeleted = bulkDeleteResponse.NumberOfDocumentsDeleted;
-                totalRequestUnitsConsumed = bulkDeleteResponse.TotalRequestUnitsConsumed;
-                totalTimeTakenSec = bulkDeleteResponse.TotalTimeTaken.TotalSeconds;
-            }
-            catch (DocumentClientException de)
-            {
-                throw new BizException("Document client exception: {0}"+ de);
-            }
-            catch (Exception e)
-            {
-                throw new BizException("Exception: "+ e);
-                
-            }
-
-            return list;
-        }
-        private static UpdateOperation SwitchType(string key, object obj)
-        {
-            Type s = obj.GetType();
-            TypeCode typeCode = Type.GetTypeCode(s);
-            return typeCode switch
-            {
-                TypeCode.String => new SetUpdateOperation<string>(key, obj.ToString()),
-                TypeCode.Int32 => new SetUpdateOperation<Int32>(key, (Int32)obj),
-                TypeCode.Double => new SetUpdateOperation<Double>(key, (Double)obj),
-                TypeCode.Byte => new SetUpdateOperation<Byte>(key, (Byte)obj),
-                TypeCode.Boolean => new SetUpdateOperation<Boolean>(key, (Boolean)obj),
-                TypeCode.DateTime => new SetUpdateOperation<DateTime>(key, (DateTime)obj),
-                TypeCode.Int64 => new SetUpdateOperation<Int64>(key, (Int64)obj),
-                _ => null,
-            };
-        }
-
-        public async Task<List<T>> FindByDict<T>(Dictionary<string, object> dict, bool IsPk=true)
-        {
-            Type t = typeof(T);
-            // List<T> objs = new List<T>();
-            DocumentCollection collection=   await InitializeCollection<T>();
-            StringBuilder sql = new StringBuilder("select value(c) from c");
-            SQLHelper.GetSQL(dict,ref sql);
-            //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = IsPk };
-            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(Database, collection.Id), sql.ToString(), queryOptions);
-            //foreach (var item in query)
-            //{
-            //    objs.Add(item);
-            //}
-            return query.ToList<T>();
-        }
-
-        private static string GenSql(object obj, string key)
-        {
-
-            if (obj is JArray array)
-            {
-                StringBuilder sql = new StringBuilder(" and  c." + key + " in (");
-                foreach (JValue obja in array)
-                {
-                    if (obja.Value is string a)
-                    {
-                        sql.Append("'" + a + "',");
-                    }
-                    if (obja.Value is int b)
-                    {
-                        sql.Append(b + ",");
-
-                    }
-                    if (obja.Value is double c)
-                    {
-                        sql.Append(c + ",");
-                    }
-                    if (obja.Value is bool d)
-                    {
-                        sql.Append(d + ",");
-
-                    }
-                    if (obja.Value is long e)
-                    {
-                        sql.Append(e + ",");
-                    }
-                    if (obja.Value is DateTime f)
-                    {
-                        sql.Append(f + ",");
-                    }
-                }
-                string sqls = sql.ToString().Substring(0, sql.Length - 1);
-                sqls += ") ";
-                return sqls;
-            }
-            else if (key.StartsWith("$."))
-            {
-                Type s = obj.GetType();
-                TypeCode typeCode = Type.GetTypeCode(s);
-                string keyLike = key.Replace("$.", "");
-                return typeCode switch
-                {
-                    TypeCode.String => "and " + "Contains( c." + keyLike + " , \'" + obj.ToString() + "\') = true ",
-                    TypeCode.Int32 => "and " + "Contains( c." + keyLike + " , \'" + int.Parse(obj.ToString()) + "\') = true ",
-                    TypeCode.Double => "and " + "Contains( c." + keyLike + " , \'" + double.Parse(obj.ToString()) + "\') = true ",
-                    //case TypeCode.Byte: return "and c." + key + "=" + (Byte)obj ;   
-                    TypeCode.Boolean => "and " + "Contains( c." + keyLike + " , \'" + bool.Parse(obj.ToString()) + "\') = true ",
-                    TypeCode.DateTime => "and " + "Contains( c." + keyLike + " , \'" + (DateTime)obj + "\') = true ",
-                    TypeCode.Int64 => "and " + "Contains( c." + keyLike + " , \'" + long.Parse(obj.ToString()) + "\') = true ",
-                    _ => null,
-                };
-            }
-            else
-            {
-
-                Type s = obj.GetType();
-                TypeCode typeCode = Type.GetTypeCode(s);
-
-                return typeCode switch
-                {
-                    TypeCode.String => " and c." + key + "=" + "'" + obj.ToString() + "'",
-                    TypeCode.Int32 => " and c." + key + "=" + int.Parse(obj.ToString()),
-                    TypeCode.Double => " and c." + key + "=" + double.Parse(obj.ToString()),
-                    //case TypeCode.Byte: return "and c." + key + "=" + (Byte)obj ;   
-                    TypeCode.Boolean => " and c." + key + "=" + bool.Parse(obj.ToString()),
-                    TypeCode.DateTime => " and c." + key + "=" + (DateTime)obj,
-                    TypeCode.Int64 => " and c." + key + "=" + long.Parse(obj.ToString()),
-                    _ => null,
-                };
-            }
-
-        }
-
-        public  IQueryable<dynamic> FindByDict(string CollectionName,  Dictionary<string, object> dict)
-        {
-            if (DocumentCollectionDict.TryGetValue(CollectionName, out DocumentCollection collection))
-            {
-                //  collection = await InitializeCollection(CollectionName, "");
-                /*    StringBuilder sql = new StringBuilder("select * from " + CollectionName + " c where 1=1 ");
-                    if (dict != null)
-                    {
-                        foreach (string key in dict.Keys)
-                        {
-                            sql.Append(GenSql(dict[key], key));
-                        }
-                    }*/
-                StringBuilder sql = new StringBuilder("select value(c) from c");
-                SQLHelper.GetSQL(dict,ref sql);
-                FeedOptions queryOptions;
-                if (collection.PartitionKey.Paths.Count > 0)
-                {
-                    queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true };
-                }
-                else
-                {
-                    queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = false };
-                }
-                //查询条数 -1是全部
-                var query = CosmosClient.CreateDocumentQuery(UriFactory.CreateDocumentCollectionUri(Database, CollectionName), sql.ToString(), queryOptions);
-                return query;
-            }
-            else {
-                throw new BizException("CollectionName named:" + CollectionName + " dose not exsit in Database!");
-            }
-            
-        }
-
-     
-
-        public IQueryable<dynamic> FindCountByDict(string CollectionName, Dictionary<string, object> dict)
-        {
-            if (DocumentCollectionDict.TryGetValue(CollectionName, out DocumentCollection collection))
-            {
-                
-                StringBuilder sql = new StringBuilder("select value count(c) from c");
-                SQLHelper.GetSQL(dict, ref sql);
-                FeedOptions queryOptions;
-                if (collection.PartitionKey.Paths.Count > 0)
-                {
-                    queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true };
-                }
-                else
-                {
-                    queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = false };
-                }
-                //查询条数 -1是全部
-                var query = CosmosClient.CreateDocumentQuery(UriFactory.CreateDocumentCollectionUri(Database, CollectionName), sql.ToString(), queryOptions);
-                return query;
-            }
-            else
-            {
-                throw new BizException("CollectionName named:" + CollectionName + " dose not exsit in Database!");
-            }
-
-        }
-        private static void GetPageNum(Dictionary<string, object> dict, ref int offsetNum, ref int limitNum, ref bool pageBool)
-        {
-            dict.TryGetValue("OFFSET", out object offset);
-            dict.Remove("OFFSET");
-            dict.TryGetValue("LIMIT", out object limit);
-            dict.Remove("LIMIT");
-            if (offset != null && limit != null)
-            {
-                pageBool = true;
-                offsetNum = int.Parse(offset.ToString());
-                limitNum = int.Parse(limit.ToString());
-            }
-        }
-    }
-}

+ 0 - 30
TEAMModelOS.SDK/Module/AzureCosmosDB/Interfaces/IAzureCosmosDBRepository.cs

@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Interfaces
-{
-    public interface IAzureCosmosDBRepository
-    {
-        Task<T> Save<T>(T entity)  ;
-        Task<T> Update<T>(T entity);
-        Task<string> ReplaceObject<T>(T entity, string key);
-        Task<string> ReplaceObject<T>(T entity, string key, string partitionKey);
-        Task<List<T>> FindAll<T>();
-        Task<string> DeleteAsync<T>(string id);
-        Task<string> DeleteAsync<T>(string id, string partitionKey);
-        Task<T> DeleteAsync<T>(T entity);
-        Task<List<T>> FindSQL<T>(string sql);
-        Task<List<T>> FindSQL<T>(string sql, bool isPK);
-        Task<List<T>> FindLinq<T>(Func<IQueryable<object>, object> singleOrDefault);
-        Task<List<T>> FindByParams<T>(Dictionary<string, object> dict);
-        Task<List<T>> FindByDict<T>(Dictionary<string, object> dict, bool isPK=true);
-        Task<List<T>> SaveAll<T>(List<T> enyites);
-        Task<List<T>> UpdateAll<T>(Dictionary<string, object> dict, Dictionary<string, object> updateFilters, List<string> deleteKeys = null);
-        Task<List<T>> DeleteAll<T>(Dictionary<string, object> dict);
-        IQueryable<dynamic> FindByDict(string CollectionName, Dictionary<string, object> dict);
-        IQueryable<dynamic> FindCountByDict(string CollectionName, Dictionary<string, object> dict);
-    }
-}

Файловите разлики са ограничени, защото са твърде много
+ 0 - 1252
TEAMModelOS.SDK/Module/AzureCosmosDBV3/AzureCosmosDBV3Repository.cs


+ 0 - 60
TEAMModelOS.SDK/Module/AzureCosmosDBV3/AzureCosmosDBV3ServiceCollectionExtensions.cs

@@ -1,60 +0,0 @@
-using Microsoft.Azure.Cosmos;
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
-using TEAMModelOS.SDK.Module.AzureCosmosDB.Interfaces;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
-{
-
-        public static class AzureCosmosDBServiceCollectionExtensions
-        {
-            /// <summary>
-            /// 
-            /// </summary>
-            /// <param name="services"></param>
-            /// <returns></returns>
-            private static AzureCosmosDBServiceBuilder AddCosmosDBServerBuilder(this IServiceCollection services)
-            {
-                return new AzureCosmosDBServiceBuilder(services);
-            }
-
-            /// <summary>
-            /// 
-            /// </summary>
-            /// <param name="services"></param>
-            /// <returns></returns>
-            public static AzureCosmosDBServiceBuilder AddAzureCosmosDBV3(this IServiceCollection services)
-            {
-                var builder = services.AddCosmosDBServerBuilder();
-                services.AddSingleton<IAzureCosmosDBV3Repository, AzureCosmosDBV3Repository>();
-                return builder;
-            }
-
-        
-            /// <summary>
-            /// 
-            /// </summary>
-            /// <param name="builder"></param>
-            /// <param name="_connectionString"></param>
-            /// <returns></returns>
-        public static AzureCosmosDBServiceBuilder AddCosmosDBV3Connection(this AzureCosmosDBServiceBuilder builder, AzureCosmosDBOptions databaseOptions)
-        {
-            builder.Services.AddSingleton(databaseOptions);
-            return builder;
-        }
-        /// <summary>
-        /// CosmosJsonDotNetSerializer  SystemTextJsonCosmosSerializer
-        /// </summary>
-        /// <param name="builder"></param>
-        /// <param name="_connectionString"></param>
-        /// <returns></returns>
-        public static AzureCosmosDBServiceBuilder AddCosmosSerializer(this AzureCosmosDBServiceBuilder builder, CosmosSerializer databaseOptions)
-            {
-                builder.Services.AddSingleton(databaseOptions);
-                return builder;
-            }
-        }
-}

+ 0 - 81
TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosDBV3ClientSingleton.cs

@@ -1,81 +0,0 @@
-using Microsoft.Azure.Cosmos;
-using Microsoft.Azure.Cosmos.Fluent;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
-{
-    public class CosmosDBV3ClientSingleton
-    {
-        private static string _connectionUrl;
-        private static string _connectionKey;
-        private static CosmosSerializer _cosmosSerializer;
-        private CosmosClient CosmosClient;
-
-        private CosmosDBV3ClientSingleton() { }
-
-
-
-        public CosmosClient GetCosmosDBClient()
-        {
-            if (CosmosClient != null)
-            {
-                return CosmosClient;
-            }
-            else
-            {
-                getInstance(_connectionUrl, _connectionKey, _cosmosSerializer);
-                return CosmosClient;
-            }
-        }
-
-        public static CosmosDBV3ClientSingleton getInstance(string connectionUrl, string connectionKey, CosmosSerializer cosmosSerializer)
-        {
-            _connectionUrl = connectionUrl;
-            _connectionKey = connectionKey;
-            _cosmosSerializer = cosmosSerializer;
-            if (cosmosSerializer != null && cosmosSerializer.GetType() == typeof(SystemTextJsonCosmosSerializer))
-            {
-                return SingletonCustomInstance.instance;
-            }
-            return SingletonInstance.instance;
-        }
-
-        private static class SingletonInstance
-        {
-            public static CosmosDBV3ClientSingleton instance = new CosmosDBV3ClientSingleton()
-            {
-                // CosmosClient    =new CosmosClient(_connectionUrl, _connectionKey, new CosmosClientOptions() { AllowBulkExecution = true } )
-                CosmosClient = new CosmosClientBuilder(_connectionUrl, _connectionKey).
-                WithBulkExecution(true).WithConnectionModeDirect()
-                //WithConnectionModeDirect().
-                .Build()
-                //CosmosClient = new CosmosClient(_connectionUrl, _connectionKey)
-            };
-            //private static readonly ConnectionPolicy ConnectionPolicy = new ConnectionPolicy
-            //{
-            //    ConnectionMode = ConnectionMode.Direct,
-            //    ConnectionProtocol = Protocol.Tcp
-            //};
-        }
-        private static class SingletonCustomInstance
-        {
-            public static CosmosDBV3ClientSingleton instance = new CosmosDBV3ClientSingleton()
-            {
-                // CosmosClient    =new CosmosClient(_connectionUrl, _connectionKey, new CosmosClientOptions() { AllowBulkExecution = true } )
-                CosmosClient = new CosmosClientBuilder(_connectionUrl, _connectionKey).
-                WithBulkExecution(true).WithConnectionModeDirect().
-                //WithConnectionModeDirect().
-                WithCustomSerializer(_cosmosSerializer).WithThrottlingRetryOptions(TimeSpan.FromSeconds(60),50)
-                .Build()
-                //CosmosClient = new CosmosClient(_connectionUrl, _connectionKey)
-            };
-            //private static readonly ConnectionPolicy ConnectionPolicy = new ConnectionPolicy
-            //{
-            //    ConnectionMode = ConnectionMode.Direct,
-            //    ConnectionProtocol = Protocol.Tcp
-            //};
-        }
-    }
-}

+ 0 - 18
TEAMModelOS.SDK/Module/AzureCosmosDBV3/CosmosDict.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
-{
-    public class CosmosDict
-    {
-        /// <summary>
-        /// 表名方式的连接
-        /// </summary>
-        public Dictionary<string, CosmosModelInfo> nameCosmos { get; set; } = new Dictionary<string, CosmosModelInfo>();
-        /// <summary>
-        /// 类类型的连接
-        /// </summary>
-        public Dictionary<string, CosmosModelInfo> typeCosmos { get; set; } = new Dictionary<string, CosmosModelInfo>();
-    }
-}

+ 0 - 97
TEAMModelOS.SDK/Module/AzureCosmosDBV3/IAzureCosmosDBV3Repository.cs

@@ -1,97 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
-{
-    /// <summary>
-    /// "$.name":"明",
-    /// "!$.name":"小"
-    /// "code.|":{"aaa"}
-    /// "<.birthday":20150101,  
-    /// "!=.type":"测试", 
-    /// "<=.day":"1515" 
-    /// ">.age.&":18, 
-    /// "codes[*]":{"aaa"}
-    /// "codes[*]":["aaa","bbb"]
-    /// "code":["aaa","bbb"]
-    /// "@OFFSET":1,
-  	/// "@LIMIT":10,
-  	/// "@DESC","crateTime"
-    /// "@ASC","crateTime"
-    /// </summary>
-    public interface IAzureCosmosDBV3Repository
-    {
-        Task<T> Save<T>(T entity) where T : ID;
-        Task<List<T>> SaveAll<T>(List<T> enyites) where T : ID;
-        Task<IdPk> DeleteAsync<T>(T entity) where T : ID;
-        Task<IdPk> DeleteAsync<T>(string id, string pk) where T : ID;
-        Task<IdPk> DeleteAsync<T>(IdPk idPk) where T : ID;
-        Task<List<IdPk>> DeleteAll<T>(List<T> entities) where T : ID;
-        Task<List<IdPk>> DeleteAll<T>(List<IdPk> ids) where T : ID;
-        Task<List<IdPk>> DeleteAll<T>(Dictionary<string, object> dict) where T : ID;
-        Task<T> Update<T>(T entity) where T : ID;
-        Task<List<T>> UpdateAll<T>(List<T> entities) where T : ID;
-        Task<List<dynamic>> UpdateAll(string typeName,List<dynamic> entities) ;
-        Task<T> SaveOrUpdate<T>(T entity) where T : ID;
-        Task<List<T>> SaveOrUpdateAll<T>(List<T> entities) where T : ID;
-     //   Task<T> FindById<T>(string id) where T : ID;
-        Task<T> FindByIdPk<T>(string id, string pk) where T : ID;
-        // Task<string> ReplaceObject<T>(T entity, string key, string partitionKey) where T : ID;
-        Task<List<T>> FindAll<T>(List<string> propertys = null) where T : ID;
-        /// <summary>
-        /// QueryText = @"SELECT *
-        //            FROM    c 
-        //            WHERE   c.documentType = @documentType 
-        //                    AND c.id = @id",
-        //Parameters = new[]
-        //{
-        //    new CosmosDbQueryParameter("@documentType", GetDocumentType<T>()),
-        //    new CosmosDbQueryParameter("@id", id)
-        //}
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="sql"></param>
-        /// <param name="Parameters"></param>
-        /// <returns></returns>
-        Task<List<T>> FindSQL<T>(string sql, Dictionary<string, object> Parameters = null) where T : ID;
-        //Task<List<T>> FindSQL<T>(string sql, bool isPK) where T : ID;
-
-        /// <summary>
-        /////正确的代码
-        //Expression<Func<QuestionFeed, bool>> predicate = null;
-        //      query = f =>  1==1;
-        //    query= query.And(x =>x.Address.City== "Seattle3");
-        //    query= query.Or(x => x.id== "Andersen.1");
-        //    query = query.And(x => x.Parents.Where(y => y.FirstName == "Thomas1").Any()) ;
-        //    Expression<Func<Family, object>> order = null;
-        //order = f => f.id;
-        //_questionFeedRepository.Entities.Where(predicate);
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="itemsPerPage"></param>
-        /// <param name="query"></param>
-        /// <returns></returns>
-        Task<List<T>> FindLinq<T>(Expression<Func<T, bool>> query = null, Expression<Func<T, object>> order = null, bool isDesc = false) where T : ID;
-        Task<List<T>> FindByParams<T>(Dictionary<string, object> dict,  List<string> propertys = null) where T : ID;
-        Task<List<T>> FindByDict<T>(Dictionary<string, object> dict,List<string> propertys = null) where T : ID;
-        Task<List<dynamic>> FindByDict(string CollectionName, Dictionary<string, object> dict, List<string> propertys = null);
-        Task<List<dynamic>> FindCountByDict(string CollectionName, Dictionary<string, object> dict);
-        Task<CosmosDict> InitializeDatabase();
-        /// <summary>
-        /// 根据ID获取  是否从cache获取  默认是
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="id"></param>
-        /// <param name="cache"></param>
-        /// <returns></returns>
-        Task<List<T>>FindById<T>(string id,bool cache=true) where T : ID;
-        Task<List<T>> FindByIds<T>(List<string> ids) where T : ID;
-        Task<dynamic> FindById(string CollectionName, string id);
-        Task<List<dynamic>> FindByIds (string CollectionName, List<string> ids);
-        Task<List<int>> FindCountByDict<T>(Dictionary<string, object> dict);
-     
-    }
-}

+ 0 - 139
TEAMModelOS.SDK/Module/AzureCosmosDBV3/PredicateExtensions.cs

@@ -1,139 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading.Tasks;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
-{
-    /// <summary>
-    //
-    /*
-               Expression<Func<UserInfo, bool>> exp = x => x.Status == (int)BizConst.UserStatus.Active;  
-               if(parameters.IsAuthenticated)
-               {
-                   exp = exp.And(x => x.IdentityAuth == (int) BizConst.IdentityAuthStatus.Authed && x.CareerAuth == (int) BizConst.GlobalCareerStatus.Authed);
-               }
-               if(parameters.IsVip)
-               {
-                   exp = exp.And(x => x.Vip != (int) BizConst.VipTag.NoVip);
-               }*/
-    /// </summary>
-    public static class PredicateExtensions
-    {
-        ///// <summary>
-        ///// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效。即,设置为True时所有or语句应该放在and语句之后,否则无效
-        ///// </summary>
-        //public static Expression<Func<T, bool>> True<T>() { return f => true; }
-
-        ///// <summary>
-        ///// 机关函数应用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混应时写在OR后面的AND有效。 即,设置为False时所有or语句应该放在and语句之前,否则无效
-        ///// </summary>
-        //public static Expression<Func<T, bool>> False<T>() { return f => false; }
-
-        //public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1,
-        //   Expression<Func<T, bool>> expression2)
-        //{
-        //    var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
-        //            .Cast<Expression>());
-
-        //    return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression),
-        //    expression1.Parameters);
-        //}
-
-        //public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
-        //      Expression<Func<T, bool>> expression2)
-        //{
-        //    var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
-        //         .Cast<Expression>());
-
-        //    return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body,
-        //           invokedExpression), expression1.Parameters);
-
-        //}
-
-
-        /// <summary>
-        /// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效。即,设置为True时所有or语句应该放在and语句之后,否则无效
-        /// </summary>
-        public static Expression<Func<T, bool>> BaseAnd<T>() { return f => true; }
-        /// <summary>
-        /// 机关函数应用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混应时写在OR后面的AND有效。 即,设置为False时所有or语句应该放在and语句之前,否则无效
-        /// </summary>
-        public static Expression<Func<T, bool>> BaseOr<T>() { return f => false; }
-
-        public static Expression<Func<T, bool>> Or<T>(
-            this Expression<Func<T, bool>> expr1,
-            Expression<Func<T, bool>> expr2)
-        {
-            var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
-            return Expression.Lambda<Func<T, bool>>
-                  (Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
-        }
-
-        public static Expression<Func<T, bool>> And<T>(
-            this Expression<Func<T, bool>> expr1,
-            Expression<Func<T, bool>> expr2)
-        {
-            var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
-            return Expression.Lambda<Func<T, bool>>
-                  (Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
-        }
-
-        public static Expression Replace(this Expression expression,
-        Expression searchEx, Expression replaceEx)
-        {
-            return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
-        }
-
-        public static Expression<Func<T, bool>> CombineOrPreicatesWithAndPredicates<T>(this Expression<Func<T, bool>> combinedPredicate,
-            Expression<Func<T, bool>> andPredicate, Expression<Func<T, bool>> orPredicate)
-        {
-            combinedPredicate = combinedPredicate ?? BaseAnd<T>();
-            if (andPredicate != null && orPredicate != null)
-            {
-                andPredicate = andPredicate.And(orPredicate);
-                combinedPredicate = combinedPredicate.And(andPredicate);
-            }
-            else if (orPredicate != null)
-            {
-                combinedPredicate = combinedPredicate.And(orPredicate);
-            }
-            else
-            {
-                combinedPredicate = combinedPredicate.And(andPredicate);
-            }
-            return combinedPredicate;
-        }
-
-        public static void AddToPredicateTypeBasedOnIfAndOrOr<T>(ref Expression<Func<T, bool>> andPredicate,
-            ref Expression<Func<T, bool>> orPredicate, Expression<Func<T, bool>> newExpression, bool isAnd)
-        {
-            if (isAnd)
-            {
-                andPredicate = andPredicate ?? BaseAnd<T>();
-                andPredicate = andPredicate.And(newExpression);
-            }
-            else
-            {
-                orPredicate = orPredicate ?? BaseOr<T>();
-                orPredicate = orPredicate.Or(newExpression);
-            }
-        }
-    }
-    internal class ReplaceVisitor : ExpressionVisitor
-    {
-        private readonly Expression from, to;
-
-        public ReplaceVisitor(Expression from, Expression to)
-        {
-            this.from = from;
-            this.to = to;
-        }
-
-        public override Expression Visit(Expression node)
-        {
-            return node == from ? to : base.Visit(node);
-        }
-    }
-}

+ 0 - 45
TEAMModelOS.SDK/Module/AzureCosmosDBV3/SystemTextJsonCosmosSerializer.cs

@@ -1,45 +0,0 @@
-using Microsoft.Azure.Cosmos;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text.Json;
-using System.Threading.Tasks;
-
-namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
-{
-    public class SystemTextJsonCosmosSerializer : CosmosSerializer
-    {
-        private readonly JsonSerializerOptions _options;
-
-        public SystemTextJsonCosmosSerializer(JsonSerializerOptions options)
-        {
-            _options = options;
-        }
-
-        /// <inheritdoc />
-        public override T FromStream<T>(Stream stream)
-        {
-            // Have to dispose of the stream, otherwise the Cosmos SDK throws.
-            // https://github.com/Azure/azure-cosmos-dotnet-v3/blob/0843cae3c252dd49aa8e392623d7eaaed7eb712b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonSerializerWrapper.cs#L22
-            // https://github.com/Azure/azure-cosmos-dotnet-v3/blob/0843cae3c252dd49aa8e392623d7eaaed7eb712b/Microsoft.Azure.Cosmos/src/Serializer/CosmosJsonDotNetSerializer.cs#L73
-            using (stream)
-            {
-                // TODO Would be more efficient if CosmosSerializer supported async
-                // See https://github.com/Azure/azure-cosmos-dotnet-v3/issues/715
-                using var memory = new MemoryStream((int)stream.Length);
-                stream.CopyTo(memory);
-
-                byte[] utf8Json = memory.ToArray();
-                return JsonSerializer.Deserialize<T>(utf8Json, _options);
-            }
-        }
-
-        /// <inheritdoc />
-        public override Stream ToStream<T>(T input)
-        {
-            byte[] utf8Json = JsonSerializer.SerializeToUtf8Bytes(input, _options);
-            return new MemoryStream(utf8Json);
-        }
-    }
-}

+ 0 - 17
TEAMModelOS.SDK/Module/AzureTable/Configuration/AzureTableOptions.cs

@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureTable.Configuration
-{
-    public class AzureTableOptions
-    {
-        public string ConnectionString { get; set; } 
-        /// <summary>
-        /// 
-        /// </summary>
-        public AzureTableOptions()
-        {
-        }
-    }
-}

+ 0 - 80
TEAMModelOS.SDK/Module/AzureTable/Configuration/HaBookTableContinuationToken.cs

@@ -1,80 +0,0 @@
-
-using Microsoft.Azure.Cosmos.Table;
-using System;
-using System.ComponentModel.DataAnnotations;
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
-using TEAMModelOS.SDK.Helper.Common.ValidateHelper;
-
-namespace TEAMModelOS.SDK.Module.AzureTable.Configuration
-{
-    
-    public class HaBookTableContinuationToken
-    {
-        [Required]
-        public string NextPartitionKey { get; set; }
-        [Required]
-        public string NextRowKey { get; set; }
-        [Required]
-        public string NextTableName { get; set; }
-        [Required]
-        public StorageLocation? TargetLocation { get; set; }
-        public TableContinuationToken GetContinuationToken() {
-            TableContinuationToken continuationToken = new TableContinuationToken
-            {
-                NextPartitionKey = this.NextPartitionKey,
-                NextRowKey = this.NextRowKey,
-                NextTableName = this.NextTableName,
-                TargetLocation = this.TargetLocation
-            };
-            return ValidateHelper.ValidObj(continuationToken);
-        }
-        public HaBookTableContinuationToken() {
-        }
-        public HaBookTableContinuationToken(TableContinuationToken continuationToken) {
-            if (null != continuationToken) {
-                this.NextPartitionKey = continuationToken.NextPartitionKey;
-                this.NextRowKey = continuationToken.NextRowKey;
-                this.NextTableName = continuationToken.NextTableName;
-                this.TargetLocation = continuationToken.TargetLocation;
-            }
-        }
-
-        public HaBookTableContinuationToken(AzureTableToken continuationToken)
-        {
-            if (null != continuationToken) {
-                this.NextPartitionKey = continuationToken.NextPartitionKey;
-                this.NextRowKey = continuationToken.NextRowKey;
-                this.NextTableName = continuationToken.NextTableName;
-                int index = 0;
-                foreach (StorageLocation item in Enum.GetValues(typeof(StorageLocation)))
-                {
-                    if (continuationToken.TargetLocation == index)
-                    {
-                        this.TargetLocation = item;
-                        break;
-                    }
-                    index++;
-                }
-            }
-        }
-        public AzureTableToken GetAzureTableToken() {
-            AzureTableToken continuationToken = new AzureTableToken
-            {
-                NextPartitionKey = this.NextPartitionKey,
-                NextRowKey = this.NextRowKey,
-                NextTableName = this.NextTableName
-            };
-            ///枚举遍历
-            ///
-            int index = 0;
-            foreach (StorageLocation item in Enum.GetValues(typeof(StorageLocation))) {
-                if (this.TargetLocation == item) {
-                    continuationToken.TargetLocation = index;
-                    break;
-                }
-                index++;
-            }
-            return ValidateHelper.ValidObj(continuationToken); 
-        }
-    }
-}

+ 0 - 758
TEAMModelOS.SDK/Module/AzureTable/Implements/AzureTableDBRepository.cs

@@ -1,758 +0,0 @@
-using TEAMModelOS.SDK.Module.AzureTable.Configuration;
-using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Helper.Security.AESCrypt;
-using TEAMModelOS.SDK.Context.Exception;
-using System.Reflection;
-using TEAMModelOS.SDK.Context.Attributes.Azure;
-using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.Context.Configuration;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Azure.Cosmos.Table;
-
-namespace TEAMModelOS.SDK.Module.AzureTable.Implements
-{    //Linq全部查詢有1000限制
-    /*
-    public async Task<List<T>> GetByPartitionKey(string partitionKey)
-    {
-        var theQuery = table.CreateQuery<T>().Where(ent => ent.PartitionKey == partitionKey);
-        TableQuerySegment<T> querySegment = null;
-        var returnList = new List<T>();
-        while (querySegment == null || querySegment.ContinuationToken != null)
-        {
-            querySegment = await theQuery.AsTableQuery()
-                   .ExecuteSegmentedAsync(querySegment != null ?
-                    querySegment.ContinuationToken : null);
-            returnList.AddRange(querySegment);
-        }
-        return returnList;
-        //Linq全部查詢沒有1000限制(要驗證)
-        public Task<List<T>> GetByPartitionKey(string partitionKey)
-        {
-            return Task.Run(() => table.CreateQuery<T>()
-                   .Where(ent => ent.PartitionKey == partitionKey)
-                   .ToList());
-        }
-    }*/
-
-    /// <summary>
-    /// 带处理问题 
-    /// 1.使用 Microsoft.Azure.Cosmos.Table
-    /// 2.AddSingleton 可能不適合CloudTableClient  线程不安全
-    /// 3.能否使用 Efcore 
-    /// 4.有CreateQuery可以用,也有AsTableQuery轉換 還有Microsoft.Azure.Cosmos.Table.Queryable 支持 Linq lambda語法
-    /// 5. 另外可以驗證一下最低查詢投影處理Count時 var query = from entity in table.CreateQuery<T>(tableName) select new { entity.PartitionKey };
-    /// 
-    /// 另外你有優化的話,順便驗證一下
-
-
-
-
-    /// </summary>
-    public class AzureTableDBRepository : IAzureTableDBRepository
-    {
-        private CloudTableClient CloudTableClient { get; set; }
-        private CloudTable cloudTable { get; set; }
-        private AzureTableOptions options { get; set; }
-
-        public AzureTableDBRepository()
-        {
-            options = BaseConfigModel.Configuration.GetSection("Azure:Table").Get<AzureTableOptions>();
-            CloudTableClient = CloudStorageAccount.Parse(options.ConnectionString).CreateCloudTableClient();
-        }
-        private string GetTableSpace<T>()
-        {
-            Type type = typeof(T);
-            string Name = type.Name;
-
-            object[] attributes = type.GetCustomAttributes(true);
-            foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
-            {
-                if (attribute is TableNameAttribute tableSpace)
-                {
-                    Name = tableSpace.Name;
-                }
-            }
-            return Name;
-        }
-        private async Task<string> InitializeTable<T>()
-        {
-
-            string TableName = GetTableSpace<T>();
-            if (cloudTable == null || !cloudTable.Name.Equals(TableName))
-            {
-                cloudTable = CloudTableClient.GetTableReference(TableName);
-                await cloudTable.CreateIfNotExistsAsync();
-            }
-            return TableName;
-        }
-
-
-
-        //Linq全部查詢有1000限制
-        //public async Task<List<T>> GetByPartitionKey<T>(string partitionKey) where T : TableEntity, new()
-        //{
-        //    var theQuery = cloudTable.CreateQuery<T>().Where(ent => ent.PartitionKey == partitionKey);
-        //    TableQuerySegment<T> querySegment = null;
-        //    var returnList = new List<T>();
-        //    while (querySegment == null || querySegment.ContinuationToken != null)
-        //    {
-        //        querySegment = await theQuery.AsTableQuery()
-        //               .ExecuteSegmentedAsync(querySegment != null ?
-        //                querySegment.ContinuationToken : null);
-        //        returnList.AddRange(querySegment);
-        //    }
-        //    return returnList;
-
-        //}
-        //Linq全部查詢沒有1000限制(要驗證)
-
-        /// <summary>
-        /// Linq全部查詢沒有1000限制(要驗證)
-        /// 就是最低消耗查詢處理Count var query = from entity in table.CreateQuery<T>(tableName) select new { entity.PartitionKey };
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="partitionKey"></param>
-        /// <returns></returns>
-        public Task<List<T>> GetByPartitionKey<T>(string partitionKey) where T : TableEntity, new()
-        {
-            return Task.Run(() => cloudTable.CreateQuery<T>()
-                   .Where(ent => ent.PartitionKey == partitionKey)
-                   .ToList());
-        }
-        public async Task<List<T>> FindAll<T>() where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            return await QueryList<T>(exQuery, TableName);
-        }
-
-        private async Task<List<T>> QueryList<T>(TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
-        {
-            TableContinuationToken continuationToken = null;
-            List<T> entitys = new List<T>();
-            do
-            {
-                var result = await CloudTableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
-                if (result.Results.Count > 0)
-                {
-                    entitys.AddRange(result.ToList());
-                }
-                continuationToken = result.ContinuationToken;
-            } while (continuationToken != null);
-            return entitys;
-        }
-
-
-        private async Task<T> QueryObject<T>(TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
-        {
-            TableContinuationToken continuationToken = null;
-            T entity = new T();
-            do
-            {
-                var result = await CloudTableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
-                if (result.Results.Count > 0)
-                {
-                    entity= result.ToList()[0];
-                    break;
-                }
-                continuationToken = result.ContinuationToken;
-            } while (continuationToken != null);
-            return entity;
-        }
-
-        public async Task<int> Count<T>(TableContinuationToken continuationToken) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            List<T> entitys = new List<T>();
-            do
-            {
-                var result = await CloudTableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
-                if (result.Results.Count > 0)
-                {
-                    entitys.AddRange(result.ToList());
-                }
-                continuationToken = result.ContinuationToken;
-            } while (continuationToken != null);
-            return entitys.Count;
-        }
-
-        public async Task<int> Count<T>() where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            TableContinuationToken continuationToken = null;
-            var exQuery = new TableQuery<T>();
-            List<T> entitys = new List<T>();
-            do
-            {
-                var result = await CloudTableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, continuationToken);
-                if (result.Results.Count > 0)
-                {
-                    entitys.AddRange(result.ToList());
-                }
-                continuationToken = result.ContinuationToken;
-            } while (continuationToken != null);
-            return entitys.Count;
-        }
-
-        public async Task<T> FindByRowKey<T>(string id) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            if (!string.IsNullOrEmpty(id))
-            {
-                string typeStr = SwitchType<T>(id, "RowKey");
-                if (string.IsNullOrEmpty(typeStr))
-                {
-                    return null;
-                }
-                exQuery.Where(typeStr);
-                // exQuery.Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, id));
-                return await QueryObject<T>(exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-
-
-        }
-
-        public async Task<List<T>> FindListByDict<T>(Dictionary<string, object> dict) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            StringBuilder builder = new StringBuilder();
-            if (null != dict && dict.Count > 0)
-            {
-                var keys = dict.Keys;
-                int index = 1;
-                foreach (string key in keys)
-                {
-                    if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
-                    {
-                        string typeStr = SwitchType<T>(dict[key], key);
-                        if (string.IsNullOrEmpty(typeStr))
-                        {
-                            continue;
-                        }
-                        if (index == 1)
-                        {
-                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append(typeStr);
-
-                        }
-                        else
-                        {
-                            //builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append("  " + TableOperators.And + "  " + typeStr);
-
-                        }
-                        index++;
-                    }
-                    else
-                    {
-                        throw new Exception("The parameter must have value!");
-                    }
-                }
-
-                exQuery.Where(builder.ToString());
-                return await QueryList<T>(exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-        }
-
-        public async Task<List<T>> FindListByKey<T>(string key, object value) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-
-            var exQuery = new TableQuery<T>();
-            if (!string.IsNullOrEmpty(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
-            {
-
-                string typeStr = SwitchType<T>(value, key);
-                if (string.IsNullOrEmpty(typeStr))
-                {
-                    return null;
-                }
-                exQuery.Where(typeStr);
-                //exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, value));
-                return await QueryList<T>(exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-
-        }
-
-        public async Task<T> FindOneByDict<T>(IDictionary<string, object> dict) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            StringBuilder builder = new StringBuilder();
-            if (null != dict && dict.Count > 0)
-            {
-                var keys = dict.Keys;
-                int index = 1;
-                foreach (string key in keys)
-                {
-                    if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
-                    {
-
-
-                        string typeStr = SwitchType<T>(dict[key], key);
-                        if (string.IsNullOrEmpty(typeStr))
-                        {
-                            continue;
-                        }
-                        if (index == 1)
-                        {
-                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append(typeStr);
-                        }
-                        else
-                        {
-                            // builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append("  " + TableOperators.And + "  " + typeStr);
-                        }
-                        index++;
-                    }
-                    else
-                    {
-                        throw new Exception("The parameter must have value!");
-                    }
-                }
-                exQuery.Where(builder.ToString());
-                return await QueryObject<T>(exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-
-        }
-
-        private static string SwitchType<T>(object obj, string key)
-        {
-            Type objType = typeof(T);
-            PropertyInfo property = objType.GetProperty(key);
-
-            //Type s = obj.GetType();
-            //TypeCode typeCode = Type.GetTypeCode(s);
-            if (property == null)
-            {
-                //return null;
-                throw new Exception(objType.FullName + " PropertyInfo doesn't include this parameter :" + key);
-            }
-            TypeCode typeCode = Type.GetTypeCode(property.PropertyType);
-
-
-            switch (typeCode)
-            {
-
-                case TypeCode.String: return TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, obj.ToString());
-                case TypeCode.Int32: return TableQuery.GenerateFilterConditionForInt(key, QueryComparisons.Equal, int.Parse(obj.ToString()));
-                case TypeCode.Double: return TableQuery.GenerateFilterConditionForDouble(key, QueryComparisons.Equal, (double)obj);
-                case TypeCode.Byte: return TableQuery.GenerateFilterConditionForBinary(key, QueryComparisons.Equal, (byte[])obj);
-                case TypeCode.Boolean: return TableQuery.GenerateFilterConditionForBool(key, QueryComparisons.Equal, (bool)obj);
-                case TypeCode.DateTime: return TableQuery.GenerateFilterConditionForDate(key, QueryComparisons.Equal, (DateTimeOffset)obj);
-                case TypeCode.Int64: return TableQuery.GenerateFilterConditionForLong(key, QueryComparisons.Equal, long.Parse(obj.ToString()));
-
-                default: return null;
-            }
-        }
-
-        public async Task<T> FindOneByKey<T>(string key, object value) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            if (!string.IsNullOrEmpty(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
-            {
-
-                string typeStr = SwitchType<T>(value, key);
-                if (string.IsNullOrEmpty(typeStr))
-                {
-                    return null;
-                }
-                exQuery.Where(typeStr);
-                //exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal,
-                //                                                          value));
-
-
-                return await QueryObject<T>(exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-
-        }
-
-        public async Task<List<T>> GetEntities<T>(IDictionary<string, object> dict) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            StringBuilder builder = new StringBuilder();
-            if (null != dict && dict.Count > 0)
-            {
-                var keys = dict.Keys;
-                int index = 1;
-                foreach (string key in keys)
-                {
-                    if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
-                    {
-                        string typeStr = SwitchType<T>(dict, key);
-                        if (string.IsNullOrEmpty(typeStr))
-                        {
-                            continue;
-                        }
-                        if (index == 1)
-                        {
-                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append(typeStr);
-
-                        }
-                        else
-                        {
-                            // builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append("  " + TableOperators.And + "  " + typeStr);
-
-                        }
-                        index++;
-                    }
-                    else
-                    {
-                        throw new Exception("The parameter must have value!");
-                    }
-                }
-                exQuery.Where(builder.ToString());
-                return await QueryList<T>(exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-        }
-
-
-
-        public async Task<List<T>> SaveAll<T>(List<T> entitys) where T : TableEntity, new()
-        {
-            if (entitys.IsEmpty())
-            {
-                return null;
-            }
-            string TableName = await InitializeTable<T>();
-            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
-            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
-            {
-                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
-                {
-                    { group.Key, group.ToList() }
-                };
-                listInfo.Add(dictInfo);
-            }
-
-            foreach (Dictionary<string, List<T>> dict in listInfo)
-            {
-                IList<TableResult> result = null;
-                foreach (string key in dict.Keys)
-                {
-                    List<T> values = dict[key];
-                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
-                    //  async range =>
-                    //  {
-                    //      TableBatchOperation batchOperation = new TableBatchOperation();
-                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
-                    //          batchOperation.Insert(values[i]);
-                    //      result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    //  });
-                    int pageSize = 100;
-                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
-                    for (int i = 0; i < pages; i++)
-                    {
-                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
-                        TableBatchOperation batchOperation = new TableBatchOperation();
-                        for (int j = 0; j < lists.Count; j++)
-                        {
-                            batchOperation.Insert(lists[j]);
-                        }
-                        result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    }
-                }
-            }
-            return entitys;
-        }
-
-        public async Task<List<T>> UpdateAll<T>(List<T> entitys) where T : TableEntity, new()
-        {
-            if (entitys.IsEmpty())
-            {
-                return null;
-            }
-            string TableName = await InitializeTable<T>();
-            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
-            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
-            {
-                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
-                {
-                    { group.Key, group.ToList() }
-                };
-                listInfo.Add(dictInfo);
-            }
-
-            foreach (Dictionary<string, List<T>> dict in listInfo)
-            {
-                IList<TableResult> result = null;
-                foreach (string key in dict.Keys)
-                {
-                    List<T> values = dict[key];
-                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
-                    //  async range =>
-                    //  {
-                    //      TableBatchOperation batchOperation = new TableBatchOperation();
-                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
-                    //          batchOperation.Replace(values[i]);
-                    //      result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    //  });
-                    int pageSize = 100;
-                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
-                    for (int i = 0; i < pages; i++)
-                    {
-                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
-                        TableBatchOperation batchOperation = new TableBatchOperation();
-                        for (int j = 0; j < lists.Count; j++)
-                        {
-                            batchOperation.Replace(lists[j]);
-                        }
-                        result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    }
-                }
-            }
-            return entitys;
-        }
-
-        public async Task<List<T>> SaveOrUpdateAll<T>(List<T> entitys) where T : TableEntity, new()
-        {
-            if (entitys.IsEmpty())
-            {
-                return null;
-            }
-            string TableName = await InitializeTable<T>();
-            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
-            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
-            {
-                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
-                {
-                    { group.Key, group.ToList() }
-                };
-                listInfo.Add(dictInfo);
-            }
-
-            foreach (Dictionary<string, List<T>> dict in listInfo)
-            {
-                IList<TableResult> result = null;
-                foreach (string key in dict.Keys)
-                {
-                    List<T> values = dict[key];
-                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 50),
-                    //  async range =>
-                    //  {
-                    //      TableBatchOperation batchOperation = new TableBatchOperation();
-                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
-                    //          batchOperation.InsertOrReplace(values[i]);
-                    //      result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    //  });
-
-                    int pageSize = 100;
-                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
-                    for (int i = 0; i < pages; i++)
-                    {
-                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
-                        TableBatchOperation batchOperation = new TableBatchOperation();
-                        for (int j = 0; j < lists.Count; j++)
-                        {
-                            batchOperation.InsertOrReplace(lists[j]);
-                        }
-                        result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    }
-                }
-            }
-            return entitys;
-        }
-
-
-
-
-        public async Task<List<T>> DeleteAll<T>(List<T> entitys) where T : TableEntity, new()
-        {
-            if (entitys.IsEmpty())
-            {
-                return null;
-            }
-            string TableName = await InitializeTable<T>();
-            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
-            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
-            {
-                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
-                {
-                    { group.Key, group.ToList() }
-                };
-                listInfo.Add(dictInfo);
-            }
-
-            foreach (Dictionary<string, List<T>> dict in listInfo)
-            {
-                IList<TableResult> result = null;
-                foreach (string key in dict.Keys)
-                {
-                    List<T> values = dict[key];
-                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
-                    //  async range =>
-                    //  {
-                    //      TableBatchOperation batchOperation = new TableBatchOperation();
-                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
-                    //          batchOperation.Delete(values[i]);
-                    //      result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    //  });
-
-                    int pageSize = 100;
-                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
-                    for (int i = 0; i < pages; i++)
-                    {
-                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
-                        TableBatchOperation batchOperation = new TableBatchOperation();
-                        for (int j = 0; j < lists.Count; j++)
-                        {
-                            batchOperation.Delete(lists[j]);
-                        }
-                        result = await CloudTableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                    }
-                }
-            }
-            return entitys;
-        }
-
-        public async Task<T> Save<T>(TableEntity entity) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            TableOperation operation = TableOperation.Insert(entity);
-            TableResult result = await CloudTableClient.GetTableReference(TableName).ExecuteAsync(operation);
-            return (T)result.Result;
-        }
-        public async Task<T> SaveOrUpdate<T>(TableEntity entity) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            TableOperation operation = TableOperation.InsertOrReplace(entity);
-            TableResult result = await CloudTableClient.GetTableReference(TableName).ExecuteAsync(operation);
-            return (T)result.Result;
-        }
-
-        public async Task<T> Update<T>(TableEntity entity) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            TableOperation operation = TableOperation.Replace(entity);
-            TableResult result = await CloudTableClient.GetTableReference(TableName).ExecuteAsync(operation);
-            return (T)result.Result;
-        }
-
-        public async Task<T> Delete<T>(TableEntity entity) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            TableOperation operation = TableOperation.Delete(entity);
-            TableResult result = await CloudTableClient.GetTableReference(TableName).ExecuteAsync(operation);
-            return (T)result.Result;
-        }
-
-
-        //public async Task<List<T>> FindListByDictAndLike<T>(Dictionary<string, object> dict, Dictionary<string, object> likeDict) where T : TableEntity, new()
-        //{
-        //    throw new NotImplementedException();
-        //}
-
-        //public async Task<List<T>> FindListByDictAndLikeAndNotEQ<T>(Dictionary<string, object> dict, Dictionary<string, object> likeDict, Dictionary<string, object> notEQDict) where T : TableEntity, new()
-        //{
-        //    throw new NotImplementedException();
-        //}
-
-        //public async Task<List<T>> FindListByDictAndLikeAndStartWith<T>(Dictionary<string, object> dict, Dictionary<string, object> likeDict, Dictionary<string, object> startDict) where T : TableEntity, new()
-        //{
-        //    throw new NotImplementedException();
-        //}
-
-        public async Task<AzurePagination<T>> FindListByDict<T>(Dictionary<string, object> dict, AzureTableToken azureTableToken) where T : TableEntity, new()
-        {
-            string TableName = await InitializeTable<T>();
-            var exQuery = new TableQuery<T>();
-            StringBuilder builder = new StringBuilder();
-            if (null != dict && dict.Count > 0)
-            {
-                var keys = dict.Keys;
-                int index = 1;
-                foreach (string key in keys)
-                {
-                    if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
-                    {
-                        string typeStr = SwitchType<T>(dict, key);
-                        if (string.IsNullOrEmpty(typeStr))
-                        {
-                            continue;
-                        }
-                        if (index == 1)
-                        {
-                            // builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                            builder.Append(typeStr);
-
-                        }
-                        else
-                        {
-                            builder.Append("  " + TableOperators.And + "  " + typeStr);
-                            //builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
-                        }
-                        index++;
-                    }
-                    else
-                    {
-                        throw new Exception("The parameter must have value!");
-                    }
-                }
-                exQuery.Where(builder.ToString());
-                return await QueryList<T>(azureTableToken, exQuery, TableName);
-            }
-            else
-            {
-                return null;
-            }
-
-        }
-        private async Task<AzurePagination<T>> QueryList<T>(AzureTableToken azureTableToken, TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
-        {
-            TableContinuationToken tableToken = new HaBookTableContinuationToken(azureTableToken).GetContinuationToken();
-            List<T> entitys = new List<T>();
-
-            var result = await CloudTableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, tableToken);
-            if (result.Results.Count > 0)
-            {
-                entitys.AddRange(result.ToList());
-            }
-            tableToken = result.ContinuationToken;
-            AzurePagination<T> pagination = new AzurePagination<T>
-            {
-                token = new HaBookTableContinuationToken(tableToken).GetAzureTableToken(),
-                data = entitys
-            };
-            return pagination;
-        }
-    }
-}

+ 0 - 41
TEAMModelOS.SDK/Module/AzureTable/Interfaces/IAzureTableDBRepository.cs

@@ -1,41 +0,0 @@
-using TEAMModelOS.SDK.Module.AzureTable.Configuration;
-using TEAMModelOS.SDK.Extension.DataResult.PageToken;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Azure.Cosmos.Table;
-
-namespace TEAMModelOS.SDK.Module.AzureTable.Interfaces
-{
-    public interface IAzureTableDBRepository
-    {
-        Task<List<T>> GetEntities<T>(IDictionary<string, object> dict) where T : TableEntity, new();
-        Task<T> FindOneByDict<T>(IDictionary<string, object> dict) where T : TableEntity, new();
-        Task<T> FindByRowKey<T>(string RowKey) where T : TableEntity, new();
-        Task<T> Save<T>(TableEntity entity) where T : TableEntity, new();
-        Task<T> Update<T>(TableEntity entity) where T : TableEntity, new();
-        Task<T> Delete<T>(TableEntity entity) where T : TableEntity, new();
-        Task<T> FindOneByKey<T>(string key, object value) where T : TableEntity, new();
-        Task<List<T>> FindListByDict<T>(Dictionary<string, object> dict) where T : TableEntity, new();
-        Task<List<T>> FindListByKey<T>(string key, object value) where T : TableEntity, new();
-        Task<List<T>> FindAll<T>() where T : TableEntity, new();
-        Task<List<T>> DeleteAll<T>(List<T> entitys) where T : TableEntity, new();
-        Task<List<T>> UpdateAll<T>(List<T> entitys) where T : TableEntity, new();
-        Task<List<T>> SaveAll<T>(List<T> entitys) where T : TableEntity, new();
-        //Task<List<T>> FindListByDictAndLike<T>(
-        //    Dictionary<string, object> dict,
-        //    Dictionary<string, object> likeDict) where T : TableEntity, new();
-        //Task<List<T>> FindListByDictAndLikeAndStartWith<T>(
-        //    Dictionary<string, object> dict,
-        //    Dictionary<string, object> likeDict,
-        //    Dictionary<string, object> startDict) where T : TableEntity, new();
-        //Task<List<T>> FindListByDictAndLikeAndNotEQ<T>(
-        //    Dictionary<string, object> dict,
-        //    Dictionary<string, object> likeDict,
-        //    Dictionary<string, object> notEQDict) where T : TableEntity, new();
-        //Task<int> Count<T>() where T : TableEntity, new();
-        //Task<AzurePagination<T>> FindListByDict<T>(Dictionary<string, object> dict, AzurePagination<T> pagination) where T : TableEntity, new();
-        Task<AzurePagination<T>> FindListByDict<T>(Dictionary<string, object> dict, AzureTableToken azureTableToken) where T : TableEntity, new();
-        Task<T> SaveOrUpdate<T>(TableEntity entity) where T : TableEntity, new();
-        Task<List<T>> SaveOrUpdateAll<T>(List<T> entitys) where T : TableEntity, new();
-    }
-}

+ 0 - 1
TEAMModelOS.SDK/Module/Cache/CSRedisCacheService.cs

@@ -1,7 +1,6 @@
 using Microsoft.Extensions.Caching.Distributed;
 using Microsoft.Extensions.Caching.Redis;
  
-using StackExchange.Redis;
 using System;
 using System.Collections.Generic;
 using System.Linq;

+ 0 - 307
TEAMModelOS.SDK/Module/Cache/RedisCacheService.cs

@@ -1,307 +0,0 @@
-using Microsoft.Extensions.Caching.Redis;
-using Newtonsoft.Json;
-using StackExchange.Redis;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace TEAMModelOS.SDK.Module.Cache
-{
-    public class RedisCacheService : ICacheService,IDisposable
-    {
-        protected IDatabase _cache;
-
-        private ConnectionMultiplexer _connection;
-
-        private readonly string _instance;
-        public RedisCacheService(RedisCacheOptions options, int database = 0)
-        {
-            _connection = ConnectionMultiplexer.Connect(options.Configuration);
-            _cache = _connection.GetDatabase(database);
-            _instance = options.InstanceName;
-        }
-
-        public string GetKeyForRedis(string key)
-        {
-            return _instance + key;
-        }/// <summary>
-         /// 验证缓存项是否存在
-         /// </summary>
-         /// <param name="key">缓存Key</param>
-         /// <returns></returns>
-        public bool Exists(string key)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-            return _cache.KeyExists(GetKeyForRedis(key));
-        }/// <summary>
-         /// 添加缓存
-         /// </summary>
-         /// <param name="key">缓存Key</param>
-         /// <param name="value">缓存Value</param>
-         /// <returns></returns>
-        public bool Add(string key, object value)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-            return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)));
-        }
-        /// <summary>
-        /// 添加缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <param name="value">缓存Value</param>
-        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param>
-        /// <param name="expiressAbsoulte">绝对过期时长</param>
-        /// <returns></returns>
-        public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-            return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), expiressAbsoulte);
-        }
-        /// <summary>
-        /// 添加缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <param name="value">缓存Value</param>
-        /// <param name="expiresIn">缓存时长</param>
-        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param>
-        /// <returns></returns>
-        public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-
-
-            return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), expiresIn);
-        }/// <summary>
-         /// 删除缓存
-         /// </summary>
-         /// <param name="key">缓存Key</param>
-         /// <returns></returns>
-        public bool Remove(string key)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-            return _cache.KeyDelete(GetKeyForRedis(key));
-        }
-        /// <summary>
-        /// 批量删除缓存
-        /// </summary>
-        /// <param name="key">缓存Key集合</param>
-        /// <returns></returns>
-        public void RemoveAll(IEnumerable<string> keys)
-        {
-            if (keys == null)
-            {
-                throw new ArgumentNullException(nameof(keys));
-            }
-
-            keys.ToList().ForEach(item => Remove(item));
-        }
-
-
-        /// <summary>
-        /// 获取缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <returns></returns>
-        public T Get<T>(string key) where T : class
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-
-            var value = _cache.StringGet(GetKeyForRedis(key));
-
-            if (!value.HasValue)
-            {
-                return default(T);
-            }
-
-            return JsonConvert.DeserializeObject<T>(value);
-        }
-
-        /// <summary>
-        /// 获取缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <returns></returns>
-        public object Get(string key)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-
-            var value = _cache.StringGet(GetKeyForRedis(key));
-
-            if (!value.HasValue)
-            {
-                return null;
-            }
-         
-
-            return JsonConvert.DeserializeObject(value);
-        }   /// <summary>
-            /// 获取缓存集合
-            /// </summary>
-            /// <param name="keys">缓存Key集合</param>
-            /// <returns></returns>
-        public IDictionary<string, object> GetAll(IEnumerable<string> keys)
-        {
-            if (keys == null)
-            {
-                throw new ArgumentNullException(nameof(keys));
-            }
-            var dict = new Dictionary<string, object>();
-
-            keys.ToList().ForEach(item => dict.Add(item, Get(GetKeyForRedis(item))));
-
-            return dict;
-        }
-
-        /// <summary>
-        /// 修改缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <param name="value">新的缓存Value</param>
-        /// <returns></returns>
-        public bool Replace(string key, object value)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-
-            if (Exists(key))
-                if (!Remove(key))
-                    return false;
-
-            return Add(key, value);
-
-        }
-        /// <summary>
-        /// 修改缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <param name="value">新的缓存Value</param>
-        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
-        /// <param name="expiressAbsoulte">绝对过期时长</param>
-        /// <returns></returns>
-        public bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-
-            if (Exists(key))
-                if (!Remove(key))
-                    return false;
-
-            return Add(key, value, expiresSliding, expiressAbsoulte);
-        }
-        /// <summary>
-        /// 修改缓存
-        /// </summary>
-        /// <param name="key">缓存Key</param>
-        /// <param name="value">新的缓存Value</param>
-        /// <param name="expiresIn">缓存时长</param>
-        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
-        /// <returns></returns>
-        public bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false)
-        {
-            if (key == null)
-            {
-                throw new ArgumentNullException(nameof(key));
-            }
-
-            if (Exists(key))
-                if (!Remove(key)) return false;
-
-            return Add(key, value, expiresIn, isSliding);
-        }
-        public void Dispose()
-        {
-            if (_connection != null)
-                _connection.Dispose();
-            GC.SuppressFinalize(this);
-        }
-
-
-        public async Task<bool> ExistsAsync(string key)
-        {
-            return await Task.Run(() => Exists(key));
-        }
-
-        public async Task<bool> AddAsync(string key, object value)
-        {
-            return await Task.Run(() => Add(key, value));
-        }
-
-        public async Task<bool> AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
-        {
-            return await Task.Run(() => Add(key, value, expiresSliding, expiressAbsoulte));
-        }
-
-        public async Task<bool> AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)
-        {
-            return await Task.Run(() => Add(key, value, expiresIn, isSliding));
-        }
-
-        public async Task<bool> RemoveAsync(string key)
-        {
-            return await Task.Run(() => Remove(key));
-        }
-
-        public async Task RemoveAllAsync(IEnumerable<string> keys)
-        {
-            await Task.Run(() => RemoveAll(keys));
-        }
-
-        public async Task<T> GetAsync<T>(string key) where T : class
-        {
-            return await Task.Run(() => Get<T>(key));
-        }
-
-        public async Task<object> GetAsync(string key)
-        {
-            return await Task.Run(() => Get(key));
-        }
-
-        public async Task<IDictionary<string, object>> GetAllAsync(IEnumerable<string> keys)
-        {
-            return await Task.Run(() => GetAll(keys));
-        }
-
-        public async Task<bool> ReplaceAsync(string key, object value)
-        {
-            return await Task.Run(() => Replace(key, value));
-        }
-
-        public async Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
-        {
-            return await Task.Run(() => Replace(key, value, expiresSliding, expiressAbsoulte));
-        }
-
-        public async Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)
-        {
-            return await Task.Run(() => Replace(key, value, expiresIn, isSliding));
-        }
-    }
-}

+ 22 - 14
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -8,8 +8,20 @@
     <PackageReleaseNotes>520发版</PackageReleaseNotes>
   </PropertyGroup>
 
+  <ItemGroup>
+    <Compile Remove="Module\AzureCosmosDBV3\**" />
+    <Compile Remove="Module\AzureCosmosDB\**" />
+    <EmbeddedResource Remove="Module\AzureCosmosDBV3\**" />
+    <EmbeddedResource Remove="Module\AzureCosmosDB\**" />
+    <None Remove="Module\AzureCosmosDBV3\**" />
+    <None Remove="Module\AzureCosmosDB\**" />
+  </ItemGroup>
+
   <ItemGroup>
     <PackageReference Include="AspectCore.Extensions.Reflection" Version="2.1.0" />
+    <PackageReference Include="Azure.Cosmos" Version="4.0.0-preview3" />
+    <PackageReference Include="Azure.Storage.Blobs.Batch" Version="12.2.1" />
+    <PackageReference Include="Azure.Storage.Queues" Version="12.3.2" />
     <PackageReference Include="ClouDASLibx" Version="1.1.4" />
     <PackageReference Include="Consul" Version="0.7.2.6" />
     <PackageReference Include="DocumentFormat.OpenXml" Version="2.10.1" />
@@ -17,32 +29,28 @@
     <PackageReference Include="Grpc.Core" Version="2.27.0" />
     <PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
     <PackageReference Include="IdentityModel" Version="4.2.0" />
-    <PackageReference Include="Jaeger" Version="0.3.7" />
+    <PackageReference Include="Jaeger" Version="[0.3.7]" />
     <PackageReference Include="LiteDB" Version="5.0.5" />
     <PackageReference Include="log4net" Version="2.0.8" />
-    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.3" />
-    <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.3" />
+    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.6" />
+    <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.6" />
     <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.3" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
-    <PackageReference Include="Microsoft.Azure.CosmosDB.BulkExecutor" Version="2.4.1-preview" />
-    <PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.10.1" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.6" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.6" />
     <PackageReference Include="Microsoft.Azure.ServiceBus" Version="4.1.3" />
     <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
-    <PackageReference Include="Microsoft.Extensions.Caching.Redis" Version="2.2.0" />
-    <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.3" />
-    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.3" />
-    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.3" />
+    <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.6" />
+    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.6" />
     <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.5.0" />
     <PackageReference Include="OpenTracing" Version="0.12.1" />
     <PackageReference Include="protobuf-net" Version="2.4.6" />
     <PackageReference Include="Scrutor" Version="3.2.0" />
+    <PackageReference Include="StackExchange.Redis" Version="2.1.58" />
     <PackageReference Include="System.Drawing.Common" Version="4.7.0" />
     <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.0" />
-    <PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />
     <PackageReference Include="XC.Framework.Security.RSAUtil" Version="1.0.1" />
-    <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.8.0" />
-    <PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="2.0.0-preview" />
+    <PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="2.0.0-preview" /> 
     <PackageReference Include="Caching.CSRedis" Version="3.5.5" />
   </ItemGroup>
 </Project>

+ 1 - 1
TEAMModelOS.Service/Models/CommonInfo/Inner/SyllabusNode.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using TEAMModelOS.SDK.Context.Attributes.Azure;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 
 namespace TEAMModelOS.Service.Models
 {

+ 2 - 2
TEAMModelOS.Service/Models/CommonInfo/ItemInfo.cs

@@ -3,14 +3,14 @@ using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.Text;
 using TEAMModelOS.SDK.Context.Attributes.Azure;
-using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.DI;
 
 namespace TEAMModelOS.Service.Models
 {
     /// <summary>
     ///  Teaching materials 教学材料  题目信息
     /// </summary>
-    [CosmosDB(RU = 400, Name = "Common", Cache =true)]
+    [CosmosDB(Database = "TEAMModelOS", RU = 400, Name = "Common", Cache =true)]
     public class ItemInfo :ID
     {
         [PartitionKey]

+ 0 - 0
TEAMModelOS.Service/Models/CommonInfo/Knowledge.cs


Някои файлове не бяха показани, защото твърде много файлове са промени