mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
- 优化 全局过滤器禁用时子查询传播问题;#1208
This commit is contained in:
parent
0eea073fae
commit
af87020090
@ -733,15 +733,6 @@
|
|||||||
<param name="modelBuilder"></param>
|
<param name="modelBuilder"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:FreeSqlDbContextExtensions.ApplyConfigurationsFromAssembly(FreeSql.ICodeFirst,System.Reflection.Assembly,System.Func{System.Type,System.Boolean})">
|
|
||||||
<summary>
|
|
||||||
根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类
|
|
||||||
</summary>
|
|
||||||
<param name="codeFirst"></param>
|
|
||||||
<param name="assembly"></param>
|
|
||||||
<param name="predicate"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:FreeSqlDbContextExtensions.CreateDbContext(IFreeSql)">
|
<member name="M:FreeSqlDbContextExtensions.CreateDbContext(IFreeSql)">
|
||||||
<summary>
|
<summary>
|
||||||
创建普通数据上下文档对象
|
创建普通数据上下文档对象
|
||||||
|
@ -144,6 +144,11 @@
|
|||||||
通用卡
|
通用卡
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:FreeSql.Tests.Issues._1208.DoorDeviceEntity.Users">
|
||||||
|
<summary>
|
||||||
|
用户
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="P:FreeSql.Tests.Issues._467.PayOrder.Money">
|
<member name="P:FreeSql.Tests.Issues._467.PayOrder.Money">
|
||||||
<summary>
|
<summary>
|
||||||
收款金额
|
收款金额
|
||||||
|
158
FreeSql.Tests/FreeSql.Tests/Issues/1208.cs
Normal file
158
FreeSql.Tests/FreeSql.Tests/Issues/1208.cs
Normal file
@ -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<UserEntity>("TenantQuery", a => a.TenantId == 100);
|
||||||
|
|
||||||
|
var userRepository = fsql.GetRepository<UserEntity>();
|
||||||
|
|
||||||
|
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<DoorDeviceEntity> 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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户
|
||||||
|
/// </summary>
|
||||||
|
[Navigate(ManyToMany = typeof(DoorDeviceUserEntity))]
|
||||||
|
public ICollection<UserEntity> Users { get; set; }
|
||||||
|
public int TenantId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -878,7 +878,7 @@ namespace FreeSql.Internal
|
|||||||
_common._orm.Aop.ParseExpressionHandler(this, args);
|
_common._orm.Aop.ParseExpressionHandler(this, args);
|
||||||
if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
|
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;
|
if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
|
||||||
}
|
}
|
||||||
switch (exp.NodeType)
|
switch (exp.NodeType)
|
||||||
@ -1239,13 +1239,18 @@ namespace FreeSql.Internal
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tsc.whereGlobalFilter?.Any() == true)
|
if (tsc.whereGlobalFilter != null)
|
||||||
|
{
|
||||||
|
if (tsc.whereGlobalFilter.Any() == false)
|
||||||
|
fsqlSelect0._whereGlobalFilter.Clear();
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var fsqlGlobalFilter = fsqlSelect0._whereGlobalFilter;
|
var fsqlGlobalFilter = fsqlSelect0._whereGlobalFilter;
|
||||||
if (fsqlGlobalFilter != tsc.whereGlobalFilter)
|
if (fsqlGlobalFilter != tsc.whereGlobalFilter)
|
||||||
fsqlGlobalFilter.AddRange(tsc.whereGlobalFilter.Where(b => !fsqlGlobalFilter.Any(a => a.Name == b.Name)));
|
fsqlGlobalFilter.AddRange(tsc.whereGlobalFilter.Where(b => !fsqlGlobalFilter.Any(a => a.Name == b.Name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (fsqlType != null)
|
else if (fsqlType != null)
|
||||||
{
|
{
|
||||||
var call3Exp = exp3tmp as MethodCallExpression;
|
var call3Exp = exp3tmp as MethodCallExpression;
|
||||||
@ -1495,8 +1500,17 @@ namespace FreeSql.Internal
|
|||||||
return $"({sql3.Replace(" \r\n", " \r\n ")})";
|
return $"({sql3.Replace(" \r\n", " \r\n ")})";
|
||||||
}
|
}
|
||||||
asSelectBefores.Clear();
|
asSelectBefores.Clear();
|
||||||
|
var tscwhereGlobalFilter = tsc.whereGlobalFilter;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tsc.whereGlobalFilter = fsqlSelect0._whereGlobalFilter; //ManyToMany 中间表过滤器
|
||||||
return ExpressionLambdaToSql(manySubSelectExpBoy, tsc);
|
return ExpressionLambdaToSql(manySubSelectExpBoy, tsc);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
tsc.whereGlobalFilter = tscwhereGlobalFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++)
|
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++)
|
||||||
{
|
{
|
||||||
var col1 = parm123Ref.RefColumns[mn];
|
var col1 = parm123Ref.RefColumns[mn];
|
||||||
@ -2280,7 +2294,7 @@ namespace FreeSql.Internal
|
|||||||
//return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn));
|
//return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ParseExpressionNoAsSelect(object sender, Aop.ParseExpressionEventArgs e, Func<Type, string, string> tableRule)
|
public static void ParseExpressionNoAsSelect(object sender, Aop.ParseExpressionEventArgs e, Func<Type, string, string> tableRule, List<GlobalFilter.Item> whereGlobalFilter)
|
||||||
{
|
{
|
||||||
if (e.Expression.NodeType != ExpressionType.Call &&
|
if (e.Expression.NodeType != ExpressionType.Call &&
|
||||||
(e.Expression as MemberExpression)?.Member.Name != "Count") return;
|
(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);
|
mtmReftbname = mtmReftbname.Substring(0, mtmReftbname.Length - commonExp._common.QuoteSqlName(exp3Tb.ColumnsByPosition[0].Attribute.Name).Length - 1);
|
||||||
var midSelect = commonExp._common._orm.Select<object>().As($"M{select._tables[0].Alias}_M{mtmReftbname}").AsType(memberTbref.RefMiddleEntityType) as Select1Provider<object>;
|
var midSelect = commonExp._common._orm.Select<object>().As($"M{select._tables[0].Alias}_M{mtmReftbname}").AsType(memberTbref.RefMiddleEntityType) as Select1Provider<object>;
|
||||||
if (tableRule != null) midSelect._tableRules.Add(tableRule);
|
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)
|
switch (commonExp._ado.DataType)
|
||||||
{
|
{
|
||||||
case DataType.Oracle:
|
case DataType.Oracle:
|
||||||
@ -2416,6 +2441,17 @@ namespace FreeSql.Internal
|
|||||||
Parameter = a.Parameter
|
Parameter = a.Parameter
|
||||||
}));
|
}));
|
||||||
if (tableRule != null) select._tableRules.Add(tableRule);
|
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)
|
while (true)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user