Set permissions in a single batch instead of one call per permission - #26126
Set permissions in a single batch instead of one call per permission#26126maliming wants to merge 2 commits into
Conversation
- Honor DisableTracking in the permission, identity, OpenIddict and IdentityServer repositories - Skip the feature value update when the stored value is unchanged
There was a problem hiding this comment.
Pull request overview
This PR improves permission update performance by batching permission state reads (instead of querying once per permission) and ensures EF Core repositories respect DisableTracking by starting queries from GetQueryableAsync(). It also avoids unnecessary writes in feature management when the value hasn’t changed.
Changes:
- Add a batched
SetAsync(IEnumerable<KeyValuePair<string,bool>> ...)flow and use it fromPermissionAppService.UpdateAsync. - Update several EF Core repositories to query via
GetQueryableAsync()(so tracking configuration is honored). - Avoid updating
FeatureValuewhen the stored value is unchanged, with added tests for event emission behavior.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestPermissionManagementProvider.cs | Adds call tracking to validate batch read/write behavior in tests. |
| modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs | Adds tests for multi-permission batch set semantics and reduced querying. |
| modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs | Adds application-level test ensuring grants/revokes are applied together and batched checks occur. |
| modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCoreResourcePermissionGrantRepository.cs | Switches to GetQueryableAsync() to respect tracking configuration. |
| modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/EfCorePermissionGrantRepository.cs | Switches to GetQueryableAsync() to respect tracking configuration. |
| modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs | Implements batched permission set logic (single read, write only diffs). |
| modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IPermissionManager.cs | Adds new batch SetAsync member to the public interface. |
| modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs | Uses the new batch API for UpdateAsync instead of per-permission calls. |
| modules/openiddict/src/Volo.Abp.OpenIddict.EntityFrameworkCore/Volo/Abp/OpenIddict/Applications/EfCoreOpenIddictApplicationRepository.cs | Switches to GetQueryableAsync() to respect tracking configuration. |
| modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/Clients/ClientRepository.cs | Switches to GetQueryableAsync() to respect tracking configuration. |
| modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs | Switches multiple queries to GetQueryableAsync() to respect tracking configuration. |
| modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs | Switches multiple queries to GetQueryableAsync() to respect tracking configuration. |
| modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementStore_Tests.cs | Adds tests asserting no update event when the value is unchanged and one update event when changed. |
| modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementStore.cs | Avoids unnecessary update when the incoming value matches the stored value. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #26126 +/- ##
==========================================
- Coverage 49.79% 49.76% -0.03%
==========================================
Files 3830 3830
Lines 133966 134269 +303
Branches 10156 10163 +7
==========================================
+ Hits 66709 66821 +112
- Misses 65247 65442 +195
+ Partials 2010 2006 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Resolve #26117
PermissionAppService.UpdateAsyncqueried the current state once per permission, so saving the permission modal ran one database round-trip per submitted permission. It now reads the whole set once and writes only the changed permissions.DisableTrackingwas silently ignored by the repositories whose queries start fromGetDbSetAsync()instead ofGetQueryableAsync(), which made the batched read track every row.