From af87020090aa76701f4f1292610f64e9b724085c Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Tue, 9 Aug 2022 13:40:39 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E5=99=A8=E7=A6=81=E7=94=A8=E6=97=B6=E5=AD=90?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=BC=A0=E6=92=AD=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?#1208?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 5 + FreeSql.Tests/FreeSql.Tests/Issues/1208.cs | 158 ++++++++++++++++++ FreeSql/Internal/CommonExpression.cs | 50 +++++- 4 files changed, 206 insertions(+), 16 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Issues/1208.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 537315e2..594fbad3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -733,15 +733,6 @@ - - - 根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类 - - - - - - 创建普通数据上下文档对象 diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 72e97ebc..a0d7a412 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -144,6 +144,11 @@ 通用卡 + + + 用户 + + 收款金额 diff --git a/FreeSql.Tests/FreeSql.Tests/Issues/1208.cs b/FreeSql.Tests/FreeSql.Tests/Issues/1208.cs new file mode 100644 index 00000000..63ec1220 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Issues/1208.cs @@ -0,0 +1,158 @@ +using FreeSql.DataAnnotations; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Issues +{ + public class _1208 + { + [Fact] + public void GlobalFilter() + { + using (var fsql = new FreeSqlBuilder() + .UseConnectionString(DataType.Sqlite, "data source=:memory:") + .UseAutoSyncStructure(true) + .Build()) + { + fsql.GlobalFilter.Apply("TenantQuery", a => a.TenantId == 100); + + var userRepository = fsql.GetRepository(); + + var deviceId = 100; + var sql = userRepository.Select + .Where(i => i.DoorDevices.AsSelect().Any(x => x.Id == deviceId)) + .OrderByDescending(true, a => a.Id) + .ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""TenantId"" +FROM ""issues1208_User"" a +WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDeviceUser"" Mx_Mi + WHERE (Mx_Mi.""UserId"" = a.""Id"") AND (exists(SELECT 1 + FROM ""issues1208_DoorDevice"" x + WHERE (x.""Id"" = 100) AND (x.""Id"" = Mx_Mi.""DoorDeviceId"") AND (x.""TenantId"" = 100) + limit 0,1)) AND (Mx_Mi.""TenantId"" = 100) + limit 0,1)) AND (a.""TenantId"" = 100) +ORDER BY a.""Id"" DESC", sql); + + sql = userRepository.Select + .Where(i => i.DoorDevices.AsSelect().DisableGlobalFilter("TenantQuery").Any(x => x.Id == deviceId)) + .OrderByDescending(true, a => a.Id) + .ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""TenantId"" +FROM ""issues1208_User"" a +WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDeviceUser"" Mx_Mi + WHERE (Mx_Mi.""UserId"" = a.""Id"") AND (exists(SELECT 1 + FROM ""issues1208_DoorDevice"" x + WHERE (x.""Id"" = 100) AND (x.""Id"" = Mx_Mi.""DoorDeviceId"") + limit 0,1)) + limit 0,1)) AND (a.""TenantId"" = 100) +ORDER BY a.""Id"" DESC", sql); + + sql = userRepository.Select.DisableGlobalFilter("TenantQuery") + .Where(i => i.DoorDevices.AsSelect().Any(x => x.Id == deviceId)) + .OrderByDescending(true, a => a.Id) + .ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""TenantId"" +FROM ""issues1208_User"" a +WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDeviceUser"" Mx_Mi + WHERE (Mx_Mi.""UserId"" = a.""Id"") AND (exists(SELECT 1 + FROM ""issues1208_DoorDevice"" x + WHERE (x.""Id"" = 100) AND (x.""Id"" = Mx_Mi.""DoorDeviceId"") + limit 0,1)) + limit 0,1)) +ORDER BY a.""Id"" DESC", sql); + + using (userRepository.DataFilter.Disable("TenantQuery")) + { + sql = userRepository.Select + .Where(i => i.DoorDevices.AsSelect().Any(x => x.Id == deviceId)) + .OrderByDescending(true, a => a.Id) + .ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""TenantId"" +FROM ""issues1208_User"" a +WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDeviceUser"" Mx_Mi + WHERE (Mx_Mi.""UserId"" = a.""Id"") AND (exists(SELECT 1 + FROM ""issues1208_DoorDevice"" x + WHERE (x.""Id"" = 100) AND (x.""Id"" = Mx_Mi.""DoorDeviceId"") + limit 0,1)) + limit 0,1)) +ORDER BY a.""Id"" DESC", sql); + } + + sql = userRepository.Select + .Where(i => i.DoorDevices.Any(x => x.Id == deviceId)) + .OrderByDescending(true, a => a.Id) + .ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""TenantId"" +FROM ""issues1208_User"" a +WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDevice"" x + WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDeviceUser"" Mx_Ma + WHERE (Mx_Ma.""DoorDeviceId"" = x.""Id"") AND (Mx_Ma.""UserId"" = a.""Id"") AND (Mx_Ma.""TenantId"" = 100) + limit 0,1)) AND (x.""Id"" = 100) AND (x.""TenantId"" = 100) + limit 0,1)) AND (a.""TenantId"" = 100) +ORDER BY a.""Id"" DESC", sql); + + sql = userRepository.Select.DisableGlobalFilter("TenantQuery") + .Where(i => i.DoorDevices.Any(x => x.Id == deviceId)) + .OrderByDescending(true, a => a.Id) + .ToSql(); + Assert.Equal(@"SELECT a.""Id"", a.""TenantId"" +FROM ""issues1208_User"" a +WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDevice"" x + WHERE (exists(SELECT 1 + FROM ""issues1208_DoorDeviceUser"" Mx_Ma + WHERE (Mx_Ma.""DoorDeviceId"" = x.""Id"") AND (Mx_Ma.""UserId"" = a.""Id"") + limit 0,1)) AND (x.""Id"" = 100) + limit 0,1)) +ORDER BY a.""Id"" DESC", sql); + } + } + + [Table(Name = "issues1208_User")] + class UserEntity + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + [Navigate(ManyToMany = typeof(DoorDeviceUserEntity))] + public ICollection DoorDevices { get; set; } + + public int TenantId { get; set; } + } + [Table(Name = "issues1208_DoorDeviceUser")] + class DoorDeviceUserEntity + { + public int UserId { get; set; } + + [Navigate(nameof(UserId))] + public UserEntity User { get; set; } + + public int DoorDeviceId { get; set; } + + [Navigate(nameof(DoorDeviceId))] + public DoorDeviceEntity DoorDevice { get; set; } + public int TenantId { get; set; } + } + [Table(Name = "issues1208_DoorDevice")] + class DoorDeviceEntity + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + /// + /// 用户 + /// + [Navigate(ManyToMany = typeof(DoorDeviceUserEntity))] + public ICollection Users { get; set; } + public int TenantId { get; set; } + } + } + +} diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 70aeb6f9..9c0bf50d 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -878,7 +878,7 @@ namespace FreeSql.Internal _common._orm.Aop.ParseExpressionHandler(this, args); if (string.IsNullOrEmpty(args.Result) == false) return args.Result; } - ParseExpressionNoAsSelect(this, args, tsc._tableRule); + ParseExpressionNoAsSelect(this, args, tsc._tableRule, tsc.whereGlobalFilter); if (string.IsNullOrEmpty(args.Result) == false) return args.Result; } switch (exp.NodeType) @@ -1239,11 +1239,16 @@ namespace FreeSql.Internal })); } } - if (tsc.whereGlobalFilter?.Any() == true) + if (tsc.whereGlobalFilter != null) { - var fsqlGlobalFilter = fsqlSelect0._whereGlobalFilter; - if (fsqlGlobalFilter != tsc.whereGlobalFilter) - fsqlGlobalFilter.AddRange(tsc.whereGlobalFilter.Where(b => !fsqlGlobalFilter.Any(a => a.Name == b.Name))); + if (tsc.whereGlobalFilter.Any() == false) + fsqlSelect0._whereGlobalFilter.Clear(); + else + { + var fsqlGlobalFilter = fsqlSelect0._whereGlobalFilter; + if (fsqlGlobalFilter != tsc.whereGlobalFilter) + fsqlGlobalFilter.AddRange(tsc.whereGlobalFilter.Where(b => !fsqlGlobalFilter.Any(a => a.Name == b.Name))); + } } } else if (fsqlType != null) @@ -1495,7 +1500,16 @@ namespace FreeSql.Internal return $"({sql3.Replace(" \r\n", " \r\n ")})"; } asSelectBefores.Clear(); - return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); + var tscwhereGlobalFilter = tsc.whereGlobalFilter; + try + { + tsc.whereGlobalFilter = fsqlSelect0._whereGlobalFilter; //ManyToMany 中间表过滤器 + return ExpressionLambdaToSql(manySubSelectExpBoy, tsc); + } + finally + { + tsc.whereGlobalFilter = tscwhereGlobalFilter; + } } for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) { @@ -2280,7 +2294,7 @@ namespace FreeSql.Internal //return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn)); } - public static void ParseExpressionNoAsSelect(object sender, Aop.ParseExpressionEventArgs e, Func tableRule) + public static void ParseExpressionNoAsSelect(object sender, Aop.ParseExpressionEventArgs e, Func tableRule, List whereGlobalFilter) { if (e.Expression.NodeType != ExpressionType.Call && (e.Expression as MemberExpression)?.Member.Name != "Count") return; @@ -2359,6 +2373,17 @@ namespace FreeSql.Internal mtmReftbname = mtmReftbname.Substring(0, mtmReftbname.Length - commonExp._common.QuoteSqlName(exp3Tb.ColumnsByPosition[0].Attribute.Name).Length - 1); var midSelect = commonExp._common._orm.Select().As($"M{select._tables[0].Alias}_M{mtmReftbname}").AsType(memberTbref.RefMiddleEntityType) as Select1Provider; if (tableRule != null) midSelect._tableRules.Add(tableRule); + if (whereGlobalFilter != null) + { + if (whereGlobalFilter.Any() == false) + midSelect._whereGlobalFilter.Clear(); + else + { + var fsqlGlobalFilter = midSelect._whereGlobalFilter; + if (fsqlGlobalFilter != whereGlobalFilter) + fsqlGlobalFilter.AddRange(whereGlobalFilter.Where(b => !fsqlGlobalFilter.Any(a => a.Name == b.Name))); + } + } switch (commonExp._ado.DataType) { case DataType.Oracle: @@ -2416,6 +2441,17 @@ namespace FreeSql.Internal Parameter = a.Parameter })); if (tableRule != null) select._tableRules.Add(tableRule); + if (whereGlobalFilter != null) + { + if (whereGlobalFilter.Any() == false) + select._whereGlobalFilter.Clear(); + else + { + var fsqlGlobalFilter = select._whereGlobalFilter; + if (fsqlGlobalFilter != whereGlobalFilter) + fsqlGlobalFilter.AddRange(whereGlobalFilter.Where(b => !fsqlGlobalFilter.Any(a => a.Name == b.Name))); + } + } } while (true) {