diff --git a/NuGet.Config b/NuGet.Config
index 08027d47f..1ef7e445d 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -1,6 +1,16 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln
index f9be2f979..d6f586903 100644
--- a/aspnet-core/LINGYUN.MicroService.All.sln
+++ b/aspnet-core/LINGYUN.MicroService.All.sln
@@ -718,6 +718,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TaskManagement.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TaskManagement.HttpApi.Client", "modules\task-management\LINGYUN.Abp.TaskManagement.HttpApi.Client\LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj", "{72D54834-7ADF-4B18-A745-FCBBC255073B}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data-protection", "data-protection", "{F6A9D966-0022-440B-AE27-564A74CDED48}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtectionManagement.Domain.Shared", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Domain.Shared\LINGYUN.Abp.DataProtectionManagement.Domain.Shared.csproj", "{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtectionManagement.Domain", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Domain\LINGYUN.Abp.DataProtectionManagement.Domain.csproj", "{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore\LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore.csproj", "{D73200F6-CBB3-4BA8-B9BF-7110AAF05596}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Wrapper", "framework\common\LINGYUN.Abp.AspNetCore.Wrapper\LINGYUN.Abp.AspNetCore.Wrapper.csproj", "{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtectionManagement.Application.Contracts", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Application.Contracts\LINGYUN.Abp.DataProtectionManagement.Application.Contracts.csproj", "{40D7A0A3-68BD-431E-A67A-E2A35508D55D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtectionManagement.Application", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Application\LINGYUN.Abp.DataProtectionManagement.Application.csproj", "{8EA8C998-F81A-46E9-8C7E-C944D2503A0A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtection.Abstractions", "framework\data-protection\LINGYUN.Abp.DataProtection.Abstractions\LINGYUN.Abp.DataProtection.Abstractions.csproj", "{47550AB9-FA06-42D6-A4B8-7DD12FE66563}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtectionManagement.HttpApi", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.HttpApi\LINGYUN.Abp.DataProtectionManagement.HttpApi.csproj", "{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1824,6 +1842,38 @@ Global
{72D54834-7ADF-4B18-A745-FCBBC255073B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72D54834-7ADF-4B18-A745-FCBBC255073B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72D54834-7ADF-4B18-A745-FCBBC255073B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Release|Any CPU.Build.0 = Release|Any CPU
+ {30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Release|Any CPU.Build.0 = Release|Any CPU
+ {835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2170,6 +2220,15 @@ Global
{1E00BE51-A1AE-447D-B6E0-F28EC12B259A} = {77ED7922-BF30-4436-8A85-78F812583913}
{61F0EEB2-5ED0-4809-8EF9-0676C7A680CE} = {77ED7922-BF30-4436-8A85-78F812583913}
{72D54834-7ADF-4B18-A745-FCBBC255073B} = {77ED7922-BF30-4436-8A85-78F812583913}
+ {F6A9D966-0022-440B-AE27-564A74CDED48} = {D52D5A11-78EF-4154-8298-267738A6715B}
+ {8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3} = {F6A9D966-0022-440B-AE27-564A74CDED48}
+ {6C0DB8F2-FB0A-4922-B8FE-177DCF37A918} = {F6A9D966-0022-440B-AE27-564A74CDED48}
+ {D73200F6-CBB3-4BA8-B9BF-7110AAF05596} = {F6A9D966-0022-440B-AE27-564A74CDED48}
+ {30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C} = {848F6760-9B11-4C9A-9843-9D71DD66D9DA}
+ {40D7A0A3-68BD-431E-A67A-E2A35508D55D} = {F6A9D966-0022-440B-AE27-564A74CDED48}
+ {8EA8C998-F81A-46E9-8C7E-C944D2503A0A} = {F6A9D966-0022-440B-AE27-564A74CDED48}
+ {47550AB9-FA06-42D6-A4B8-7DD12FE66563} = {529DF802-97C4-4BF2-BE7C-39663B3D9EA3}
+ {835E51CE-1E6B-4C8C-9736-8C5B61F5E08E} = {F6A9D966-0022-440B-AE27-564A74CDED48}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}
diff --git a/aspnet-core/LINGYUN.MicroService.TaskManagement.sln b/aspnet-core/LINGYUN.MicroService.TaskManagement.sln
index 326be95d8..0c9439676 100644
--- a/aspnet-core/LINGYUN.MicroService.TaskManagement.sln
+++ b/aspnet-core/LINGYUN.MicroService.TaskManagement.sln
@@ -24,6 +24,12 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C99728F6-FB3C-4D26-8917-1D30725209B9}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
+ ..\common.props = ..\common.props
+ ..\common.secrets.props = ..\common.secrets.props
+ ..\configureawait.props = ..\configureawait.props
+ ..\Directory.Build.props = ..\Directory.Build.props
+ ..\Directory.Packages.props = ..\Directory.Packages.props
+ ..\NuGet.Config = ..\NuGet.Config
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "provider", "provider", "{385578CC-C0F1-4377-A7A2-682B8F416234}"
@@ -144,6 +150,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.HttpApi.Client", "modules\oss-management\LINGYUN.Abp.OssManagement.HttpApi.Client\LINGYUN.Abp.OssManagement.HttpApi.Client.csproj", "{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks.Tests", "tests\LINGYUN.Abp.BackgroundTasks.Tests\LINGYUN.Abp.BackgroundTasks.Tests.csproj", "{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TestsBase", "tests\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj", "{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Activities.Tests", "tests\LINGYUN.Abp.BackgroundTasks.Activities.Tests\LINGYUN.Abp.BackgroundTasks.Activities.Tests.csproj", "{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -374,6 +386,18 @@ Global
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -435,6 +459,9 @@ Global
{94D1C512-09E4-4A68-8989-6DB49FEABA67} = {F36E71F7-B05F-4513-A923-81E2A7474EAE}
{96B4D255-BB21-4BAF-902A-ADE3F25A44C2} = {F36E71F7-B05F-4513-A923-81E2A7474EAE}
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0} = {F36E71F7-B05F-4513-A923-81E2A7474EAE}
+ {A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C} = {77341F31-F54C-436A-AF8D-F78D91303C45}
+ {6CC06BD8-FA30-45E0-BD3A-25FF39906EF5} = {77341F31-F54C-436A-AF8D-F78D91303C45}
+ {3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07} = {77341F31-F54C-436A-AF8D-F78D91303C45}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293}
diff --git a/aspnet-core/NuGet.Config b/aspnet-core/NuGet.Config
index ec54fa98b..3f0e00340 100644
--- a/aspnet-core/NuGet.Config
+++ b/aspnet-core/NuGet.Config
@@ -1,7 +1,6 @@
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN/Abp/Authorization/OrganizationUnits/AbpOrganizationUnitClaimTypes.cs b/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN/Abp/Authorization/OrganizationUnits/AbpOrganizationUnitClaimTypes.cs
index 2287adbbe..5802bd095 100644
--- a/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN/Abp/Authorization/OrganizationUnits/AbpOrganizationUnitClaimTypes.cs
+++ b/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN/Abp/Authorization/OrganizationUnits/AbpOrganizationUnitClaimTypes.cs
@@ -2,5 +2,5 @@
public static class AbpOrganizationUnitClaimTypes
{
- public static string OrganizationUnit { get; set; } = "organization_unit";
+ public static string OrganizationUnit { get; set; } = "ou_code";
}
diff --git a/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/System/Security/Principal/AbpClaimOrganizationUnitsExtensions.cs b/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/System/Security/Principal/AbpClaimOrganizationUnitsExtensions.cs
index 72cf691d9..0106f7873 100644
--- a/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/System/Security/Principal/AbpClaimOrganizationUnitsExtensions.cs
+++ b/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/System/Security/Principal/AbpClaimOrganizationUnitsExtensions.cs
@@ -1,6 +1,5 @@
using JetBrains.Annotations;
using LINGYUN.Abp.Authorization.OrganizationUnits;
-using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Volo.Abp;
@@ -9,26 +8,16 @@ namespace System.Security.Principal;
public static class AbpClaimOrganizationUnitsExtensions
{
- public static Guid[] FindOrganizationUnits([NotNull] this ClaimsPrincipal principal)
+ public static string[] FindOrganizationUnits([NotNull] this ClaimsPrincipal principal)
{
Check.NotNull(principal, nameof(principal));
var userOusOrNull = principal.Claims?.Where(c => c.Type == AbpOrganizationUnitClaimTypes.OrganizationUnit);
if (userOusOrNull == null || !userOusOrNull.Any())
{
- return new Guid[0];
+ return new string[0];
}
- var userOus = new List();
-
- foreach (var userOusClaim in userOusOrNull)
- {
- if (Guid.TryParse(userOusClaim.Value, out var guid))
- {
- userOus.Add(guid);
- }
- }
-
- return userOus.ToArray();
+ return userOusOrNull.Select(x => x.Value).ToArray();
}
}
diff --git a/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/Volo/Abp/Users/CurrentUserOrganizationUnitsExtensions.cs b/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/Volo/Abp/Users/CurrentUserOrganizationUnitsExtensions.cs
index 4711f9ec7..838bca322 100644
--- a/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/Volo/Abp/Users/CurrentUserOrganizationUnitsExtensions.cs
+++ b/aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/Volo/Abp/Users/CurrentUserOrganizationUnitsExtensions.cs
@@ -2,29 +2,20 @@
using LINGYUN.Abp.Authorization.OrganizationUnits;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace Volo.Abp.Users;
public static class CurrentUserOrganizationUnitsExtensions
{
- public static Guid[] FindOrganizationUnits([NotNull] this ICurrentUser currentUser)
+ public static string[] FindOrganizationUnits([NotNull] this ICurrentUser currentUser)
{
var organizationUnits = currentUser.FindClaims(AbpOrganizationUnitClaimTypes.OrganizationUnit);
if (organizationUnits.IsNullOrEmpty())
{
- return new Guid[0];
+ return new string[0];
}
- var userOus = new List();
-
- foreach (var userOusClaim in organizationUnits)
- {
- if (Guid.TryParse(userOusClaim.Value, out var guid))
- {
- userOus.Add(guid);
- }
- }
-
- return userOus.ToArray();
+ return organizationUnits.Select(x => x.Value).ToArray();
}
}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xml b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xml
new file mode 100644
index 000000000..00e1d9a1c
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xsd b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xsd
new file mode 100644
index 000000000..3f3946e28
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN.Abp.DataProtection.Abstractions.csproj b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN.Abp.DataProtection.Abstractions.csproj
new file mode 100644
index 000000000..41542b6b4
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN.Abp.DataProtection.Abstractions.csproj
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/AbpDataProtectionAbstractionsModule.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/AbpDataProtectionAbstractionsModule.cs
new file mode 100644
index 000000000..dad08b9da
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/AbpDataProtectionAbstractionsModule.cs
@@ -0,0 +1,9 @@
+using Volo.Abp.Modularity;
+using Volo.Abp.ObjectExtending;
+
+namespace LINGYUN.Abp.DataProtection;
+
+[DependsOn(typeof(AbpObjectExtendingModule))]
+public class AbpDataProtectionAbstractionsModule : AbpModule
+{
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterGroup.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterGroup.cs
new file mode 100644
index 000000000..31cbecc58
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterGroup.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace LINGYUN.Abp.DataProtection;
+
+[Serializable]
+public class DataAccessFilterGroup
+{
+ public List Groups { get; set; }
+ public List Rules { get; set; }
+ public DataAccessFilterLogic Logic { get; set; }
+
+ public DataAccessFilterGroup() : this(DataAccessFilterLogic.And)
+ {
+ }
+
+ public DataAccessFilterGroup(DataAccessFilterLogic logic = DataAccessFilterLogic.And)
+ {
+ Logic = logic;
+ Rules = new List();
+ Groups = new List();
+ }
+
+ public DataAccessFilterGroup AddRule(DataAccessFilterRule rule)
+ {
+ if (Rules.All(m => !m.Equals(rule)))
+ {
+ Rules.Add(rule);
+ }
+
+ return this;
+ }
+
+ public DataAccessFilterGroup AddRule(string field, object value, DataAccessFilterOperate operate = DataAccessFilterOperate.Equal)
+ {
+ return AddRule(new DataAccessFilterRule(field, value, operate));
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterLogic.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterLogic.cs
new file mode 100644
index 000000000..f3bd98ae8
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterLogic.cs
@@ -0,0 +1,19 @@
+using System.ComponentModel;
+
+namespace LINGYUN.Abp.DataProtection;
+///
+/// 数据过滤连接方式
+///
+public enum DataAccessFilterLogic
+{
+ ///
+ /// 且
+ ///
+ [Description("且")]
+ And,
+ ///
+ /// 或
+ ///
+ [Description("或")]
+ Or
+}
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterOperate.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterOperate.cs
new file mode 100644
index 000000000..844f4e424
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterOperate.cs
@@ -0,0 +1,69 @@
+using System.ComponentModel;
+
+namespace LINGYUN.Abp.DataProtection;
+///
+/// 数据过滤操作
+///
+public enum DataAccessFilterOperate
+{
+ ///
+ /// 且
+ ///
+ [Description("且")]
+ And = 1,
+ ///
+ /// 或
+ ///
+ [Description("或")]
+ Or = 2,
+ ///
+ /// 等于
+ ///
+ [Description("等于")]
+ Equal = 3,
+ ///
+ /// 不等于
+ ///
+ [Description("不等于")]
+ NotEqual = 4,
+ ///
+ /// 小于
+ ///
+ [Description("小于")]
+ Less = 5,
+ ///
+ /// 小于或等于
+ ///
+ [Description("小于等于")]
+ LessOrEqual = 6,
+ ///
+ /// 大于
+ ///
+ [Description("大于")]
+ Greater = 7,
+ ///
+ /// 大于或等于
+ ///
+ [Description("大于等于")]
+ GreaterOrEqual = 8,
+ ///
+ /// 左包含
+ ///
+ [Description("左包含")]
+ StartsWith = 9,
+ ///
+ /// 右包含
+ ///
+ [Description("右包含")]
+ EndsWith = 10,
+ ///
+ /// 包含
+ ///
+ [Description("包含")]
+ Contains = 11,
+ ///
+ /// 不包含
+ ///
+ [Description("不包含")]
+ NotContains = 12,
+}
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterRule.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterRule.cs
new file mode 100644
index 000000000..868e72bb1
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterRule.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace LINGYUN.Abp.DataProtection;
+
+[Serializable]
+public class DataAccessFilterRule
+{
+ ///
+ /// 字段名称
+ ///
+ public string Field { get; set; }
+ ///
+ /// 字段值
+ ///
+ public object Value { get; set; }
+ ///
+ /// 操作类型
+ ///
+ public DataAccessFilterOperate Operate { get; set; }
+ ///
+ /// 左侧条件
+ ///
+ public bool IsLeft { get; set; }
+
+ public DataAccessFilterRule()
+ {
+
+ }
+
+ public DataAccessFilterRule(string field, object value, DataAccessFilterOperate operate = DataAccessFilterOperate.Equal, bool isLeft = false)
+ {
+ Field = field;
+ Value = value;
+ Operate = operate;
+ IsLeft = isLeft;
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessKeywords.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessKeywords.cs
new file mode 100644
index 000000000..8cb58adcc
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessKeywords.cs
@@ -0,0 +1,15 @@
+namespace LINGYUN.Abp.DataProtection;
+///
+/// 系统保留关键字列表
+///
+public static class DataAccessKeywords
+{
+ ///
+ /// 授权角色
+ ///
+ public const string AUTH_ROLES = "AR";
+ ///
+ /// 授权组织机构
+ ///
+ public const string AUTH_ORGS = "AO";
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessOperation.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessOperation.cs
new file mode 100644
index 000000000..9fdfcc500
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessOperation.cs
@@ -0,0 +1,24 @@
+using System.ComponentModel;
+
+namespace LINGYUN.Abp.DataProtection;
+///
+/// 数据操作
+///
+public enum DataAccessOperation
+{
+ ///
+ /// 查询
+ ///
+ [Description("查询")]
+ Read,
+ ///
+ /// 更新
+ ///
+ [Description("更新")]
+ Write,
+ ///
+ /// 删除
+ ///
+ [Description("删除")]
+ Delete
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResource.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResource.cs
new file mode 100644
index 000000000..27959a51b
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResource.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.DataProtection;
+
+[Serializable]
+public class DataAccessResource
+{
+ ///
+ /// 权限主体
+ ///
+ public string SubjectName { get; set; }
+
+ ///
+ /// 权限主体标识
+ ///
+ public string SubjectId { get; set; }
+
+ ///
+ /// 实体类型全名
+ ///
+ public string EntityTypeFullName { get; set; }
+
+ ///
+ /// 数据权限操作
+ ///
+ public DataAccessOperation Operation { get; set; }
+
+ ///
+ /// 获取或设置 数据过滤规则
+ ///
+ public DataAccessFilterGroup FilterGroup { get; set; }
+
+ ///
+ /// 允许操作的属性列表
+ ///
+ public List AllowProperties { get; set; }
+
+ public DataAccessResource()
+ {
+
+ }
+
+ public DataAccessResource(
+ string subjectName,
+ string subjectId,
+ string entityTypeFullName,
+ DataAccessOperation operation,
+ DataAccessFilterGroup filterGroup = null)
+ {
+ SubjectName = subjectName;
+ SubjectId = subjectId;
+ EntityTypeFullName = entityTypeFullName;
+ Operation = operation;
+ FilterGroup = filterGroup;
+ AllowProperties = new List();
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataProtectedAttribute.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataProtectedAttribute.cs
new file mode 100644
index 000000000..6de026f74
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataProtectedAttribute.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace LINGYUN.Abp.DataProtection;
+
+[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
+public class DataProtectedAttribute : Attribute
+{
+ public DataAccessOperation Operation { get; }
+ public DataProtectedAttribute() : this(DataAccessOperation.Read)
+ {
+ }
+
+ public DataProtectedAttribute(DataAccessOperation operation)
+ {
+ Operation = operation;
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DisableDataProtectedAttribute.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DisableDataProtectedAttribute.cs
new file mode 100644
index 000000000..9c8731596
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DisableDataProtectedAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace LINGYUN.Abp.DataProtection;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
+public class DisableDataProtectedAttribute : Attribute
+{
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtected.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtected.cs
new file mode 100644
index 000000000..2b3829e2c
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtected.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.Data;
+
+namespace LINGYUN.Abp.DataProtection;
+
+public interface IDataProtected : IHasExtraProperties
+{
+
+}
\ No newline at end of file
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtectedEnabled.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtectedEnabled.cs
new file mode 100644
index 000000000..dc4942f0e
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtectedEnabled.cs
@@ -0,0 +1,4 @@
+namespace LINGYUN.Abp.DataProtection;
+public interface IDataProtectedEnabled
+{
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/DataProtectionResource.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/DataProtectionResource.cs
new file mode 100644
index 000000000..fff292666
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/DataProtectionResource.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.Localization;
+
+namespace LINGYUN.Abp.DataProtection.Localization;
+
+[LocalizationResourceName("DataProtection")]
+public class DataProtectionResource
+{
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedReadEntityInterceptor.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedReadEntityInterceptor.cs
new file mode 100644
index 000000000..b1f3e5b5f
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedReadEntityInterceptor.cs
@@ -0,0 +1,64 @@
+using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.Extensions.Options;
+using System;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Users;
+
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
+public class AbpDataProtectedReadEntityInterceptor : IQueryExpressionInterceptor, ITransientDependency
+{
+ public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!;
+ public IOptions DataProtectionOptions => LazyServiceProvider.LazyGetRequiredService>();
+ public ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService();
+ public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService();
+ public IEntityTypeFilterBuilder EntityTypeFilterBuilder => LazyServiceProvider.LazyGetRequiredService();
+
+ private static readonly MethodInfo WhereMethodInfo = typeof(Queryable).GetMethods().First(m => m.Name == nameof(Queryable.Where));
+
+ public Expression QueryCompilationStarting(Expression queryExpression, QueryExpressionEventData eventData)
+ {
+ if (DataFilter.IsEnabled() && queryExpression.Type.GenericTypeArguments.Length > 0)
+ {
+ var entityType = queryExpression.Type.GenericTypeArguments[0];
+ var exp = EntityTypeFilterBuilder.Build(entityType, DataAccessOperation.Read);
+
+ return Expression.Call(
+ method: WhereMethodInfo.MakeGenericMethod(entityType),
+ arg0: queryExpression,
+ arg1: exp);
+ }
+
+ return queryExpression;
+ }
+
+ public class DataProtectedExpressionVisitor : ExpressionVisitor
+ {
+ private readonly Type _entityType;
+ private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
+
+ public DataProtectedExpressionVisitor(Type entityType, IEntityTypeFilterBuilder entityTypeFilterBuilder)
+ {
+ _entityType = entityType;
+ _entityTypeFilterBuilder = entityTypeFilterBuilder;
+ }
+
+ private static readonly MethodInfo WhereMethodInfo = typeof(Queryable).GetMethods().First(m => m.Name == nameof(Queryable.Where));
+
+ protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
+ {
+ var method = WhereMethodInfo.MakeGenericMethod(_entityType);
+ var args0 = base.VisitMethodCall(methodCallExpression);
+ var args1 = _entityTypeFilterBuilder.Build(_entityType, DataAccessOperation.Read);
+
+ return Expression.Call(
+ method: method,
+ arg0: args0,
+ arg1: args1);
+ }
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWriteEntityInterceptor.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWriteEntityInterceptor.cs
new file mode 100644
index 000000000..59b497734
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWriteEntityInterceptor.cs
@@ -0,0 +1,66 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Authorization;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Users;
+
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
+public class AbpDataProtectedWriteEntityInterceptor : SaveChangesInterceptor, ITransientDependency
+{
+ public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!;
+ public IOptions DataProtectionOptions => LazyServiceProvider.LazyGetRequiredService>();
+ public ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService();
+ public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService();
+ public IDataAuthorizationService DataAuthorizationService => LazyServiceProvider.LazyGetRequiredService();
+
+ public async override ValueTask> SavingChangesAsync(
+ DbContextEventData eventData,
+ InterceptionResult result,
+ CancellationToken cancellationToken = default)
+ {
+ if (DataFilter.IsEnabled() && eventData.Context != null)
+ {
+ var updateEntites = eventData.Context.ChangeTracker.Entries()
+ .Where(entry => entry.State.IsIn(EntityState.Modified) && (entry.Entity is not ISoftDelete || entry.Entity is ISoftDelete delete && delete.IsDeleted == false))
+ .Select(entry => entry.Entity as IEntity);
+ if (updateEntites.Any())
+ {
+ var updateGrant = await DataAuthorizationService.AuthorizeAsync(DataAccessOperation.Write, updateEntites);
+ if (!updateGrant.Succeeded)
+ {
+ var entityKeys = updateEntites
+ .Select(entity => (entity is IEntity abpEntity ? abpEntity.GetKeys() : new string[1] { entity.ToString() }).ToString())
+ .JoinAsString(";");
+ throw new AbpAuthorizationException(
+ $"Delete data permission not granted to entity {updateEntites.First().GetType()} for data {entityKeys}!");
+ }
+ }
+
+ var deleteEntites = eventData.Context.ChangeTracker.Entries()
+ .Where(entry => entry.State.IsIn(EntityState.Deleted) || entry.Entity is ISoftDelete delete && delete.IsDeleted == true)
+ .Select(entry => entry.Entity as IEntity);
+ if (deleteEntites.Any())
+ {
+ var deleteGrant = await DataAuthorizationService.AuthorizeAsync(DataAccessOperation.Delete, deleteEntites);
+ if (!deleteGrant.Succeeded)
+ {
+ var entityKeys = deleteEntites
+ .Select(entity => (entity is IEntity abpEntity ? abpEntity.GetKeys() : new string[1] { entity.ToString() }).ToString())
+ .JoinAsString(";");
+ throw new AbpAuthorizationException(
+ $"Delete data permission not granted to entity {deleteEntites.First().GetType()} for data {entityKeys}!");
+ }
+ }
+ }
+ return await base.SavingChangesAsync(eventData, result, cancellationToken);
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWritePropertiesInterceptor.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWritePropertiesInterceptor.cs
new file mode 100644
index 000000000..fd64ab0c5
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWritePropertiesInterceptor.cs
@@ -0,0 +1,52 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Users;
+
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
+public class AbpDataProtectedWritePropertiesInterceptor : SaveChangesInterceptor, ITransientDependency
+{
+ public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!;
+ public IOptions DataProtectionOptions => LazyServiceProvider.LazyGetRequiredService>();
+ public ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService();
+ public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService();
+
+ public async override ValueTask> SavingChangesAsync(DbContextEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
+ {
+ if (DataFilter.IsEnabled() && eventData.Context != null)
+ {
+ foreach (var entry in eventData.Context.ChangeTracker.Entries().ToList())
+ {
+ if (entry.State.IsIn(EntityState.Modified))
+ {
+ var allowProperties = new List();
+ var entity = entry.Entity;
+ var subjectContext = new DataAccessSubjectContributorContext(entity.GetType().FullName, DataAccessOperation.Write, LazyServiceProvider);
+ foreach (var contributor in DataProtectionOptions.Value.SubjectContributors)
+ {
+ var properties = contributor.GetAllowProperties(subjectContext);
+ allowProperties.AddIfNotContains(properties);
+ }
+
+ allowProperties.AddIfNotContains(DataProtectionOptions.Value.IgnoreAuditedProperties);
+
+ foreach (var property in entry.Properties)
+ {
+ if (!allowProperties.Contains(property.Metadata.Name))
+ {
+ property.IsModified = false;
+ }
+ }
+ }
+ }
+ }
+ return await base.SavingChangesAsync(eventData, result, cancellationToken);
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs
index 1c8e0b466..09b24b506 100644
--- a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs
@@ -1,145 +1,55 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
-using System;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using System.Collections.Generic;
using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using Volo.Abp.Domain.Entities;
+using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
-using Volo.Abp.MultiTenancy;
-using Volo.Abp.Uow;
using Volo.Abp.Users;
-namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
-{
- public class AbpDataProtectionDbContext : AbpDbContext
- {
- protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetService();
-
- protected virtual bool IsDataAccessFilterEnabled => DataFilter?.IsEnabled() ?? false;
-
- public AbpDataProtectionDbContext(
- DbContextOptions options) : base(options)
- {
- }
-
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- base.OnModelCreating(modelBuilder);
-
- foreach (var entityType in modelBuilder.Model.GetEntityTypes())
- {
- if (typeof(IHasDataAccess).IsAssignableFrom(entityType.ClrType))
- {
- modelBuilder.Entity(entityType.ClrType)
- .OwnsOne(entityType.ClrType.FullName, nameof(IHasDataAccess.Owner), ownedNavigationBuilder =>
- {
- ownedNavigationBuilder.ToJson();
- });
- }
- }
- }
-
- protected override void ApplyAbpConceptsForAddedEntity(EntityEntry entry)
- {
- base.ApplyAbpConceptsForAddedEntity(entry);
- if (CurrentUser.IsAuthenticated)
- {
- if (entry is IHasDataAccess entity)
- {
- ProtectedEntityHelper.TrySetOwner(
- entity,
- () => new DataAccessOwner(
- CurrentUser.Id,
- CurrentUser.Roles,
- CurrentUser.FindOrganizationUnits().Select(ou => ou.ToString()).ToArray()));
- }
- }
- }
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
- protected virtual DataAccessRuleInfo AccessRuleInfo => UnitOfWorkManager.Current.GetAccessRuleInfo();
-
- protected override void HandlePropertiesBeforeSave()
- {
- foreach (var item in ChangeTracker.Entries().ToList())
- {
- HandleExtraPropertiesOnSave(item);
- HandleCheckPropertiesOnSave(item);
- if (item.State.IsIn(EntityState.Modified, EntityState.Deleted))
- {
- UpdateConcurrencyStamp(item);
- }
- }
- }
+public abstract class AbpDataProtectionDbContext : AbpDbContext
+ where TDbContext : DbContext
+{
+ public IOptions DataProtectionOptions => LazyServiceProvider.LazyGetRequiredService>();
+ public ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService();
- protected virtual void HandleCheckPropertiesOnSave(EntityEntry entry)
- {
- // 仅当启用过滤器时检查
- if (IsDataAccessFilterEnabled)
- {
- var entityAccessRules = AccessRuleInfo?.Rules.Where(r => r.EntityTypeFullName == entry.Metadata.ClrType.FullName);
- if (entityAccessRules != null)
- {
- if (entry.State.IsIn(EntityState.Modified, EntityState.Added, EntityState.Deleted))
- {
- var entityAccessRule = entityAccessRules.FirstOrDefault(r => r.Operation.IsIn(DataAccessOperation.Write, DataAccessOperation.Delete));
- if (entityAccessRule != null)
- {
- if (entityAccessRule.Fileds.Count != 0)
- {
- var notAccessProps = entry.Properties.Where(p => !entityAccessRule.Fileds.Any(f => f.Field == p.Metadata.Name));
- if (notAccessProps != null)
- {
- foreach (var property in notAccessProps)
- {
- // 无字段权限不做变更
- property.CurrentValue = property.OriginalValue;
- }
- }
- }
- }
- else
- {
- // 无实体变更权限不做修改
- entry.State = EntityState.Unchanged;
- }
- }
- }
- }
- }
+ public AbpDataProtectionDbContext(
+ DbContextOptions options) : base(options)
+ {
+ }
- protected override Expression> CreateFilterExpression()
- {
- var expression = base.CreateFilterExpression();
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ base.OnConfiguring(optionsBuilder);
- if (typeof(IHasDataAccess).IsAssignableFrom(typeof(TEntity)))
- {
- Expression> expression2 = (TEntity e) => !IsDataAccessFilterEnabled || CreateFilterExpression(e, AccessRuleInfo);
- expression = (Expression>)((expression == null) ? ((LambdaExpression)expression2) : ((LambdaExpression)QueryFilterExpressionHelper.CombineExpressions(expression, expression2)));
- }
+ // TODO: 需要优化表达式树
+ // optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService());
+ //optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService());
+ optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService());
+ }
- return expression;
- }
+ protected override void ApplyAbpConceptsForAddedEntity(EntityEntry entry)
+ {
+ base.ApplyAbpConceptsForAddedEntity(entry);
+ SetAuthorizationDataProperties(entry);
+ }
- protected static bool CreateFilterExpression(TEntity entity, DataAccessRuleInfo accessRuleInfo)
+ protected virtual void SetAuthorizationDataProperties(EntityEntry entry)
+ {
+ if (entry.Entity is IDataProtected data)
{
- if (accessRuleInfo == null)
+ // TODO: 埋点, 以后可用EF.Functions查询
+ if (data.GetProperty(DataAccessKeywords.AUTH_ROLES) == null)
{
- return true;
+ data.SetProperty(DataAccessKeywords.AUTH_ROLES, CurrentUser.Roles.Select(role => $"[{role}]").JoinAsString(","));
}
-
- if (!accessRuleInfo.Rules.Any(r => r.EntityTypeFullName == typeof(TEntity).FullName))
+ if (data.GetProperty(DataAccessKeywords.AUTH_ORGS) == null)
{
- return false;
+ data.SetProperty(DataAccessKeywords.AUTH_ORGS, CurrentUser.FindOrganizationUnits().Select(ou => $"[{ou}]").JoinAsString(","));
}
-
- if (entity is not IHasDataAccess accessEntity)
- {
- return true;
- }
-
- // TODO: 需要完成详细的过滤条件
- return false;
}
}
}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContextModelBuilderExtensions.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContextModelBuilderExtensions.cs
new file mode 100644
index 000000000..1db3a21b1
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContextModelBuilderExtensions.cs
@@ -0,0 +1,16 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
+{
+ public static class AbpDataProtectionDbContextModelBuilderExtensions
+ {
+ public static void ConfigureLocalization(
+ this ModelBuilder builder,
+ Action optionsAction = null)
+ {
+ Check.NotNull(builder, nameof(builder));
+ }
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionEntityFrameworkCoreModule.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionEntityFrameworkCoreModule.cs
index dfcc97027..46ac1c20f 100644
--- a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionEntityFrameworkCoreModule.cs
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionEntityFrameworkCoreModule.cs
@@ -1,12 +1,11 @@
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
-namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
+
+[DependsOn(
+ typeof(AbpDataProtectionModule),
+ typeof(AbpEntityFrameworkCoreModule))]
+public class AbpDataProtectionEntityFrameworkCoreModule : AbpModule
{
- [DependsOn(
- typeof(AbpDataProtectionModule),
- typeof(AbpEntityFrameworkCoreModule))]
- public class AbpDataProtectionEntityFrameworkCoreModule : AbpModule
- {
- }
}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionModelBuilderConfigurationOptions.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionModelBuilderConfigurationOptions.cs
new file mode 100644
index 000000000..54400dd7f
--- /dev/null
+++ b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionModelBuilderConfigurationOptions.cs
@@ -0,0 +1,18 @@
+using JetBrains.Annotations;
+using Volo.Abp.EntityFrameworkCore.Modeling;
+
+namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
+{
+ public class AbpDataProtectionModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
+ {
+ public AbpDataProtectionModelBuilderConfigurationOptions(
+ [NotNull] string tablePrefix = "",
+ [CanBeNull] string schema = null)
+ : base(
+ tablePrefix,
+ schema)
+ {
+
+ }
+ }
+}
diff --git a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionAsyncQueryableProvider.cs b/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionAsyncQueryableProvider.cs
deleted file mode 100644
index 65a957292..000000000
--- a/aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionAsyncQueryableProvider.cs
+++ /dev/null
@@ -1,358 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Query.Internal;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Threading;
-using System.Threading.Tasks;
-using Volo.Abp.DependencyInjection;
-using Volo.Abp.Linq;
-
-namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
-{
- ///
- /// TODO: 需要实现动态数据权限规则
- ///
- [Dependency(ReplaceServices = true)]
- public class DataProtectionAsyncQueryableProvider : IAsyncQueryableProvider, ISingletonDependency
- {
- public bool CanExecute(IQueryable queryable)
- {
- return queryable.Provider is EntityQueryProvider;
- }
-
- public Task ContainsAsync(IQueryable queryable, T item, CancellationToken cancellationToken = default)
- {
- return queryable.ContainsAsync(item, cancellationToken);
- }
-
- public Task AnyAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AnyAsync(cancellationToken);
- }
-
- public Task AnyAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.AnyAsync(predicate, cancellationToken);
- }
-
- public Task AllAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.AllAsync(predicate, cancellationToken);
- }
-
- public Task CountAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.CountAsync(cancellationToken);
- }
-
- public Task CountAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.CountAsync(predicate, cancellationToken);
- }
-
- public Task LongCountAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.LongCountAsync(cancellationToken);
- }
-
- public Task LongCountAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.LongCountAsync(predicate, cancellationToken);
- }
-
- public Task FirstAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.FirstAsync(cancellationToken);
- }
-
- public Task FirstAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.FirstAsync(predicate, cancellationToken);
- }
-
- public Task FirstOrDefaultAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.FirstOrDefaultAsync(cancellationToken);
- }
-
- public Task FirstOrDefaultAsync(IQueryable queryable, Expression> predicate,
- CancellationToken cancellationToken = default)
- {
- return queryable.FirstOrDefaultAsync(predicate, cancellationToken);
- }
-
- public Task LastAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.LastAsync(cancellationToken);
- }
-
- public Task LastAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.LastAsync(predicate, cancellationToken);
- }
-
- public Task LastOrDefaultAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.LastOrDefaultAsync(cancellationToken);
- }
-
- public Task LastOrDefaultAsync(IQueryable queryable, Expression> predicate,
- CancellationToken cancellationToken = default)
- {
- return queryable.LastOrDefaultAsync(predicate, cancellationToken);
- }
-
- public Task SingleAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SingleAsync(cancellationToken);
- }
-
- public Task SingleAsync(IQueryable queryable, Expression> predicate, CancellationToken cancellationToken = default)
- {
- return queryable.SingleAsync(predicate, cancellationToken);
- }
-
- public Task SingleOrDefaultAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SingleOrDefaultAsync(cancellationToken);
- }
-
- public Task SingleOrDefaultAsync(IQueryable queryable, Expression> predicate,
- CancellationToken cancellationToken = default)
- {
- return queryable.SingleOrDefaultAsync(predicate, cancellationToken);
- }
-
- public Task MinAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.MinAsync(cancellationToken);
- }
-
- public Task MinAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.MinAsync(selector, cancellationToken);
- }
-
- public Task MaxAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.MaxAsync(cancellationToken);
- }
-
- public Task MaxAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.MaxAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task SumAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.SumAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(cancellationToken);
- }
-
- public Task AverageAsync(IQueryable queryable, Expression> selector, CancellationToken cancellationToken = default)
- {
- return queryable.AverageAsync(selector, cancellationToken);
- }
-
- public Task AverageAsync(IQueryable