From 428ee19d3e0313674ba4988414f772a112500273 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 03:48:40 +0000 Subject: [PATCH 1/3] Initial plan From ffad7dcda3c5eeead00228326c6b07f038256e54 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 03:51:05 +0000 Subject: [PATCH 2/3] fix: append tenant filter in interceptor query path Co-authored-by: nygula <13066114+nygula@users.noreply.github.com> --- XCode/Membership/ITenantSource.cs | 10 ++++ .../Membership/TenantContextTests.cs | 57 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/XCode/Membership/ITenantSource.cs b/XCode/Membership/ITenantSource.cs index 51e99d8e5..eb647b01f 100644 --- a/XCode/Membership/ITenantSource.cs +++ b/XCode/Membership/ITenantSource.cs @@ -189,4 +189,14 @@ protected override Boolean OnValid(IEntity entity, DataMethod method) return true; } + + /// 查询时自动附加租户过滤条件,无需在业务代码中手动调用 ApplyTenant + /// 实体工厂 + /// 查询条件表达式 + /// 查询操作来源 + /// 修改后的查询条件,已合并租户过滤 + protected override XCode.Expression? OnQuery(IEntityFactory factory, XCode.Expression? where, QueryAction action) + { + return (where & XCode.Expression.Empty).ApplyTenant(factory); + } } diff --git a/XUnitTest.XCode/Membership/TenantContextTests.cs b/XUnitTest.XCode/Membership/TenantContextTests.cs index 492657bce..b766cf3d4 100644 --- a/XUnitTest.XCode/Membership/TenantContextTests.cs +++ b/XUnitTest.XCode/Membership/TenantContextTests.cs @@ -324,6 +324,63 @@ public void TenantModule_OnValid_Delete_MismatchTenantId_ThrowsException() } #endregion + #region TenantModule.OnQuery 测试 + [Fact] + [DisplayName("OnQuery_有租户上下文时自动追加TenantId条件")] + public void TenantModule_OnQuery_WithContext_AddsTenantFilter() + { + // Arrange + var module = new TenantInterceptor(); + TenantContext.Current = new TenantContext { TenantId = 123 }; + var factory = TenantTestEntity.Meta.Factory; + + // Act + var result = module.Query(factory, null, QueryAction.FindAll); + + // Assert + var sql = result.ToString(); + Assert.Contains("TenantId", sql); + Assert.Contains("123", sql); + } + + [Fact] + [DisplayName("OnQuery_有原始条件时合并租户条件")] + public void TenantModule_OnQuery_WithExistingWhere_MergesTenantFilter() + { + // Arrange + var module = new TenantInterceptor(); + TenantContext.Current = new TenantContext { TenantId = 456 }; + var factory = TenantTestEntity.Meta.Factory; + var where = TenantTestEntity._.Name == "Stone"; + + // Act + var result = module.Query(factory, where, QueryAction.FindAll); + + // Assert + var sql = result.ToString(); + Assert.Contains("Name", sql); + Assert.Contains("Stone", sql); + Assert.Contains("TenantId", sql); + Assert.Contains("456", sql); + } + + [Fact] + [DisplayName("OnQuery_无租户上下文时不追加TenantId条件")] + public void TenantModule_OnQuery_WithoutContext_DoesNotAddTenantFilter() + { + // Arrange + var module = new TenantInterceptor(); + TenantContext.Current = null!; + var factory = TenantTestEntity.Meta.Factory; + + // Act + var result = module.Query(factory, null, QueryAction.FindAll); + + // Assert + Assert.True(result.IsEmpty); + } + #endregion + #region TenantSourceHelper.ApplyTenant 测试 [Fact] [DisplayName("ApplyTenant_有租户上下文时添加条件")] From 45a634abc692a9117753fcf0731af857f00e06e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 03:57:09 +0000 Subject: [PATCH 3/3] test: cover additional tenant OnQuery scenarios Co-authored-by: nygula <13066114+nygula@users.noreply.github.com> --- .../Membership/TenantContextTests.cs | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/XUnitTest.XCode/Membership/TenantContextTests.cs b/XUnitTest.XCode/Membership/TenantContextTests.cs index b766cf3d4..b169ba334 100644 --- a/XUnitTest.XCode/Membership/TenantContextTests.cs +++ b/XUnitTest.XCode/Membership/TenantContextTests.cs @@ -326,8 +326,8 @@ public void TenantModule_OnValid_Delete_MismatchTenantId_ThrowsException() #region TenantModule.OnQuery 测试 [Fact] - [DisplayName("OnQuery_有租户上下文时自动追加TenantId条件")] - public void TenantModule_OnQuery_WithContext_AddsTenantFilter() + [DisplayName("OnQuery_有租户上下文时FindAll空查询自动追加TenantId条件")] + public void TenantModule_OnQuery_WithContext_FindAllNullWhere_AddsTenantFilter() { // Arrange var module = new TenantInterceptor(); @@ -344,14 +344,33 @@ public void TenantModule_OnQuery_WithContext_AddsTenantFilter() } [Fact] - [DisplayName("OnQuery_有原始条件时合并租户条件")] - public void TenantModule_OnQuery_WithExistingWhere_MergesTenantFilter() + [DisplayName("OnQuery_有租户上下文时Find空查询自动追加TenantId条件")] + public void TenantModule_OnQuery_WithContext_FindNullWhere_AddsTenantFilter() + { + // Arrange + var module = new TenantInterceptor(); + TenantContext.Current = new TenantContext { TenantId = 321 }; + var factory = TenantTestEntity.Meta.Factory; + + // Act + var result = module.Query(factory, null, QueryAction.Find); + + // Assert + var sql = result.ToString(); + Assert.Contains("TenantId", sql); + Assert.Contains("321", sql); + } + + [Fact] + [DisplayName("OnQuery_有租户且已有WhereExpression时合并租户条件")] + public void TenantModule_OnQuery_WithTenantAndWhereExpression_MergesTenantFilter() { // Arrange var module = new TenantInterceptor(); TenantContext.Current = new TenantContext { TenantId = 456 }; var factory = TenantTestEntity.Meta.Factory; - var where = TenantTestEntity._.Name == "Stone"; + var where = new WhereExpression(); + where &= TenantTestEntity._.Name == "Stone"; // Act var result = module.Query(factory, where, QueryAction.FindAll); @@ -365,8 +384,24 @@ public void TenantModule_OnQuery_WithExistingWhere_MergesTenantFilter() } [Fact] - [DisplayName("OnQuery_无租户上下文时不追加TenantId条件")] - public void TenantModule_OnQuery_WithoutContext_DoesNotAddTenantFilter() + [DisplayName("OnQuery_TenantId为0时不过滤可见全部")] + public void TenantModule_OnQuery_TenantIdZero_DoesNotAddTenantFilter() + { + // Arrange + var module = new TenantInterceptor(); + TenantContext.Current = new TenantContext { TenantId = 0 }; + var factory = TenantTestEntity.Meta.Factory; + + // Act + var result = module.Query(factory, null, QueryAction.FindAll); + + // Assert + Assert.True(result.IsEmpty); + } + + [Fact] + [DisplayName("OnQuery_无租户上下文时不报错且不追加TenantId条件")] + public void TenantModule_OnQuery_WithoutContext_DoesNotThrow() { // Arrange var module = new TenantInterceptor(); @@ -374,9 +409,11 @@ public void TenantModule_OnQuery_WithoutContext_DoesNotAddTenantFilter() var factory = TenantTestEntity.Meta.Factory; // Act + var error = Record.Exception(() => module.Query(factory, null, QueryAction.FindAll)); var result = module.Query(factory, null, QueryAction.FindAll); // Assert + Assert.Null(error); Assert.True(result.IsEmpty); } #endregion