mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 优化 WithTempQuery 场景的 DTO 映射查询;
This commit is contained in:
		@@ -733,6 +733,15 @@
 | 
			
		||||
            <param name="modelBuilder"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </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)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            创建普通数据上下文档对象
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ namespace FreeSql.Tests.Internal
 | 
			
		||||
                   (name, type, value) =>
 | 
			
		||||
                      {
 | 
			
		||||
                          if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1);
 | 
			
		||||
                          var ret = new SqlParameter { ParameterName = $"@{name}", Value = value };
 | 
			
		||||
                          var ret = new SqlParameter { ParameterName = name, Value = value };
 | 
			
		||||
                          return ret;
 | 
			
		||||
                      });
 | 
			
		||||
            Assert.Single(ps);
 | 
			
		||||
@@ -39,7 +39,7 @@ namespace FreeSql.Tests.Internal
 | 
			
		||||
                   (name, type, value) =>
 | 
			
		||||
                   {
 | 
			
		||||
                       if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1);
 | 
			
		||||
                       var ret = new SqlParameter { ParameterName = $"@{name}", Value = value };
 | 
			
		||||
                       var ret = new SqlParameter { ParameterName = name, Value = value };
 | 
			
		||||
                       return ret;
 | 
			
		||||
                   });
 | 
			
		||||
            Assert.Single(ps2);
 | 
			
		||||
@@ -55,7 +55,7 @@ namespace FreeSql.Tests.Internal
 | 
			
		||||
            Func<string, Type, object, DbParameter> constructorParamter = (name, type, value) =>
 | 
			
		||||
                               {
 | 
			
		||||
                                   if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1);
 | 
			
		||||
                                   var ret = new SqlParameter { ParameterName = $"@{name}", Value = value };
 | 
			
		||||
                                   var ret = new SqlParameter { ParameterName = name, Value = value };
 | 
			
		||||
                                   return ret;
 | 
			
		||||
                               };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,83 @@ namespace FreeSql.Tests.SqlServer
 | 
			
		||||
{
 | 
			
		||||
    public class SqlServerSelectWithTempQueryTest
 | 
			
		||||
    {
 | 
			
		||||
        #region issues #1215
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void IssuesWithTempQueryAndDto()
 | 
			
		||||
        {
 | 
			
		||||
            var fsql = g.sqlserver;
 | 
			
		||||
            var lpsPgi = fsql.Select<UnitLog, LoadPlan, Instruction>()
 | 
			
		||||
                .InnerJoin((a, b, c) => a.LoadNo == b.LoadNo && a.UnitTransactionType == "TO")
 | 
			
		||||
                .InnerJoin((a, b, c) => b.InstructionNo == c.InstructionNo)
 | 
			
		||||
                .WithTempQuery((a, b, c) => new
 | 
			
		||||
                {
 | 
			
		||||
                    a.LoadNo,
 | 
			
		||||
                    a.SeqNoLog,
 | 
			
		||||
                    c.DeliveryInstractionStatus,
 | 
			
		||||
                    c.UpTime, 
 | 
			
		||||
                    RN = SqlExt.RowNumber().Over().PartitionBy(a.UnitId).OrderByDescending(a.SeqNoLog).ToValue()
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var sql = fsql.Select<UnitLog>()
 | 
			
		||||
                .FromQuery(lpsPgi)
 | 
			
		||||
                .InnerJoin((a, b) => a.SeqNoLog == b.SeqNoLog)
 | 
			
		||||
                .WithTempQuery((a, b) => new { Item1 = a, Item2 = b })
 | 
			
		||||
                .From<Unit>()
 | 
			
		||||
                .InnerJoin((a, b) => a.Item1.UnitId == b.UnitId)
 | 
			
		||||
                .Where((a, b) => a.Item2.RN < 2)
 | 
			
		||||
                .ToSql((a, b) => new MB51_View
 | 
			
		||||
                {
 | 
			
		||||
                    //CkassIfCation = a.Item1.CkassIfCation,
 | 
			
		||||
                    PGI = a.Item2.DeliveryInstractionStatus,
 | 
			
		||||
                    PGITime = a.Item2.UpTime,
 | 
			
		||||
                    IsDelayPGI = true,
 | 
			
		||||
                    RunNo = b.RunNo
 | 
			
		||||
                });
 | 
			
		||||
            Assert.Equal(@"SELECT a.[CkassIfCation] as1, a.[DeliveryInstractionStatus] as2, a.[UpTime] as3, 1 as4, b.[RunNo] as5 
 | 
			
		||||
FROM ( 
 | 
			
		||||
    SELECT a.[UnitId], a.[LoadNo], a.[UnitTransactionType], a.[SeqNoLog], a.[CkassIfCation], b.[LoadNo] [LoadNo2], b.[SeqNoLog] [SeqNoLog2], b.[DeliveryInstractionStatus], b.[UpTime], b.[RN] 
 | 
			
		||||
    FROM [UnitLog] a 
 | 
			
		||||
    INNER JOIN ( 
 | 
			
		||||
        SELECT a.[LoadNo], a.[SeqNoLog], c.[DeliveryInstractionStatus], c.[UpTime], row_number() over( partition by a.[UnitId] order by a.[SeqNoLog] desc) [RN] 
 | 
			
		||||
        FROM [UnitLog] a 
 | 
			
		||||
        INNER JOIN [LoadPlan] b ON a.[LoadNo] = b.[LoadNo] AND a.[UnitTransactionType] = N'TO' 
 | 
			
		||||
        INNER JOIN [Instruction] c ON b.[InstructionNo] = c.[InstructionNo] ) b ON a.[SeqNoLog] = b.[SeqNoLog] ) a 
 | 
			
		||||
INNER JOIN [Unit] b ON a.[UnitId] = b.[UnitId] 
 | 
			
		||||
WHERE (a.[RN] < 2)", sql);
 | 
			
		||||
        }
 | 
			
		||||
        class MB51_View
 | 
			
		||||
        {
 | 
			
		||||
            public string CkassIfCation { get; set; }
 | 
			
		||||
            public string PGI { get; set; }
 | 
			
		||||
            public DateTime PGITime { get; set; }
 | 
			
		||||
            public bool IsDelayPGI { get; set; }
 | 
			
		||||
            public string RunNo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
        class Unit
 | 
			
		||||
        {
 | 
			
		||||
            public string UnitId { get; set; }
 | 
			
		||||
            public string RunNo { get; set; }
 | 
			
		||||
            public string CkassIfCation { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
        class UnitLog
 | 
			
		||||
        {
 | 
			
		||||
            public string UnitId { get; set; }
 | 
			
		||||
            public string LoadNo { get; set; }
 | 
			
		||||
            public string UnitTransactionType { get; set; }
 | 
			
		||||
            public string SeqNoLog { get; set; }
 | 
			
		||||
            public string CkassIfCation { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
        class LoadPlan
 | 
			
		||||
        {
 | 
			
		||||
            public string LoadNo { get; set; }
 | 
			
		||||
            public string InstructionNo { get; set; }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        class Instruction
 | 
			
		||||
        {
 | 
			
		||||
            public string InstructionNo { get; set; }
 | 
			
		||||
            public string DeliveryInstractionStatus { get; set; }
 | 
			
		||||
            public DateTime UpTime { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void IssuesParameter01()
 | 
			
		||||
@@ -49,13 +125,15 @@ INNER JOIN [QLR_TO_LSH] b ON a.[BBH] = b.[BBH] AND b.[QLRZJHM] = N'qlrzjh' AND b
 | 
			
		||||
                    .First();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        class QLR_TO_LSH 
 | 
			
		||||
        class QLR_TO_LSH
 | 
			
		||||
        {
 | 
			
		||||
            public string QLRZJHM { get; set; }
 | 
			
		||||
            public string QZH { get; set; }
 | 
			
		||||
            public int BBH { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #region issues #1215
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void VicDemo20220815()
 | 
			
		||||
        {
 | 
			
		||||
@@ -1275,7 +1353,7 @@ WHERE ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))";
 | 
			
		||||
                .InnerJoin((a, b) => a.user.Id == b.UserId)
 | 
			
		||||
                .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02")
 | 
			
		||||
                .ToSql((a, b) => new TwoTablePartitionBy_UserDto());
 | 
			
		||||
            var assertSql08 = @"SELECT a.[rownum] as1, b.[Remark] as2 
 | 
			
		||||
            var assertSql08 = @"SELECT a.[Id] as1, a.[rownum] as2, b.[Remark] as3 
 | 
			
		||||
FROM ( 
 | 
			
		||||
    SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] 
 | 
			
		||||
    FROM [TwoTablePartitionBy_User] a ) a 
 | 
			
		||||
@@ -1298,10 +1376,10 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .ToList<TwoTablePartitionBy_UserDto>();
 | 
			
		||||
            Assert.Equal(list08.Count, 2);
 | 
			
		||||
            Assert.Equal(list08[0].rownum, 1);
 | 
			
		||||
            Assert.Equal(list08[0].Id, 0);
 | 
			
		||||
            Assert.Equal(list08[0].Id, 4);
 | 
			
		||||
            Assert.Equal(list08[0].remark, "remark04");
 | 
			
		||||
            Assert.Equal(list08[1].rownum, 1);
 | 
			
		||||
            Assert.Equal(list08[1].Id, 0);
 | 
			
		||||
            Assert.Equal(list08[1].Id, 5);
 | 
			
		||||
            Assert.Equal(list08[1].remark, "remark05");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1316,7 +1394,7 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .InnerJoin((a, b) => a.user.Id == b.UserId)
 | 
			
		||||
                .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02")
 | 
			
		||||
                .ToSql((a, b) => new TwoTablePartitionBy_UserDto());
 | 
			
		||||
            var assertSql09 = @"SELECT a.[rownum] as1, b.[Remark] as2 
 | 
			
		||||
            var assertSql09 = @"SELECT a.[Id] as1, a.[rownum] as2, b.[Remark] as3 
 | 
			
		||||
FROM ( 
 | 
			
		||||
    SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] 
 | 
			
		||||
    FROM [TwoTablePartitionBy_User] a ) a 
 | 
			
		||||
@@ -1339,10 +1417,10 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .ToList<TwoTablePartitionBy_UserDto>();
 | 
			
		||||
            Assert.Equal(list09.Count, 2);
 | 
			
		||||
            Assert.Equal(list09[0].rownum, 1);
 | 
			
		||||
            Assert.Equal(list09[0].Id, 0);
 | 
			
		||||
            Assert.Equal(list09[0].Id, 4);
 | 
			
		||||
            Assert.Equal(list09[0].remark, "remark04");
 | 
			
		||||
            Assert.Equal(list09[1].rownum, 1);
 | 
			
		||||
            Assert.Equal(list09[1].Id, 0);
 | 
			
		||||
            Assert.Equal(list09[1].Id, 5);
 | 
			
		||||
            Assert.Equal(list09[1].remark, "remark05");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1357,7 +1435,7 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .InnerJoin((a, b) => a.user.Id == b.UserId)
 | 
			
		||||
                .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02")
 | 
			
		||||
                .ToSql((a, b) => new TwoTablePartitionBy_UserDto());
 | 
			
		||||
            var assertSql091 = @"SELECT a.[rownum] as1, b.[Remark] as2 
 | 
			
		||||
            var assertSql091 = @"SELECT a.[Id] as1, a.[rownum] as2, b.[Remark] as3 
 | 
			
		||||
FROM ( 
 | 
			
		||||
    SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] 
 | 
			
		||||
    FROM [TwoTablePartitionBy_User] a ) a 
 | 
			
		||||
@@ -1381,10 +1459,10 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .ToList<TwoTablePartitionBy_UserDto>();
 | 
			
		||||
            Assert.Equal(list091.Count, 2);
 | 
			
		||||
            Assert.Equal(list091[0].rownum, 1);
 | 
			
		||||
            Assert.Equal(list091[0].Id, 0);
 | 
			
		||||
            Assert.Equal(list091[0].Id, 4);
 | 
			
		||||
            Assert.Equal(list091[0].remark, "remark04");
 | 
			
		||||
            Assert.Equal(list091[1].rownum, 1);
 | 
			
		||||
            Assert.Equal(list091[1].Id, 0);
 | 
			
		||||
            Assert.Equal(list091[1].Id, 5);
 | 
			
		||||
            Assert.Equal(list091[1].remark, "remark05");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1399,7 +1477,7 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .InnerJoin((a, b) => a.user.Id == b.Key.UserId)
 | 
			
		||||
                .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02")
 | 
			
		||||
                .ToSql((a, b) => new TwoTablePartitionBy_UserDto());
 | 
			
		||||
            var assertSql10 = @"SELECT a.[rownum] as1 
 | 
			
		||||
            var assertSql10 = @"SELECT a.[Id] as1, a.[rownum] as2, b.[Remark] as3 
 | 
			
		||||
FROM ( 
 | 
			
		||||
    SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] 
 | 
			
		||||
    FROM [TwoTablePartitionBy_User] a ) a 
 | 
			
		||||
@@ -1423,11 +1501,11 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .ToList<TwoTablePartitionBy_UserDto>();
 | 
			
		||||
            Assert.Equal(list10.Count, 2);
 | 
			
		||||
            Assert.Equal(list10[0].rownum, 1);
 | 
			
		||||
            Assert.Equal(list10[0].Id, 0);
 | 
			
		||||
            Assert.Null(list10[0].remark);
 | 
			
		||||
            Assert.Equal(list10[0].Id, 4);
 | 
			
		||||
            Assert.Equal(list10[0].remark, "remark04");
 | 
			
		||||
            Assert.Equal(list10[1].rownum, 1);
 | 
			
		||||
            Assert.Equal(list10[1].Id, 0);
 | 
			
		||||
            Assert.Null(list10[1].remark);
 | 
			
		||||
            Assert.Equal(list10[1].Id, 5);
 | 
			
		||||
            Assert.Equal(list10[1].remark, "remark05");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var sql11 = fsql.Select<TwoTablePartitionBy_User>()
 | 
			
		||||
@@ -1441,7 +1519,7 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .InnerJoin((a, b) => a.user.Id == b.uid)
 | 
			
		||||
                .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02")
 | 
			
		||||
                .ToSql((a, b) => new TwoTablePartitionBy_UserDto());
 | 
			
		||||
            var assertSql11 = @"SELECT a.[rownum] as1 
 | 
			
		||||
            var assertSql11 = @"SELECT a.[Id] as1, a.[rownum] as2 
 | 
			
		||||
FROM ( 
 | 
			
		||||
    SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] 
 | 
			
		||||
    FROM [TwoTablePartitionBy_User] a ) a 
 | 
			
		||||
@@ -1465,11 +1543,11 @@ WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02
 | 
			
		||||
                .ToList<TwoTablePartitionBy_UserDto>();
 | 
			
		||||
            Assert.Equal(list11.Count, 2);
 | 
			
		||||
            Assert.Equal(list11[0].rownum, 1);
 | 
			
		||||
            Assert.Equal(list11[0].Id, 0);
 | 
			
		||||
            Assert.Equal(list11[0].Id, 4);
 | 
			
		||||
            Assert.Null(list11[0].remark);
 | 
			
		||||
            Assert.Equal(list11[1].rownum, 1);
 | 
			
		||||
            Assert.Equal(list11[1].Id, 0);
 | 
			
		||||
            Assert.Null(list11[1].remark);
 | 
			
		||||
            Assert.Equal(list11[1].Id, 5);
 | 
			
		||||
            Assert.Null(list11[0].remark);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var sql12 = fsql.Select<TwoTablePartitionBy_User>()
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ namespace FreeSql.Tests.SqliteExpression
 | 
			
		||||
            }.Any(b => b.Name1 == a.Name && b.Click1 == a.Click || a.Click > 10)).ToSql();
 | 
			
		||||
            Assert.Equal(@"SELECT a.""Id"", a.""Name"", a.""Click"" 
 | 
			
		||||
FROM ""ArrayAny01"" a 
 | 
			
		||||
WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10))", t1);
 | 
			
		||||
WHERE ((('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10)))", t1);
 | 
			
		||||
 | 
			
		||||
            var t2 = fsql.Select<ArrayAny01>().Where(a => new[] {
 | 
			
		||||
                new ArrayAny02 { Name1 = "name01", Click1 = 1 },
 | 
			
		||||
@@ -36,7 +36,7 @@ WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10))", t1);
 | 
			
		||||
            }.Any(b => b.Name1 == a.Name && b.Click1 == a.Click || a.Click > 10)).ToSql();
 | 
			
		||||
            Assert.Equal(@"SELECT a.""Id"", a.""Name"", a.""Click"" 
 | 
			
		||||
FROM ""ArrayAny01"" a 
 | 
			
		||||
WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name02' = a.""Name"" AND 2 = a.""Click"" OR a.""Click"" > 10))", t2);
 | 
			
		||||
WHERE ((('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name02' = a.""Name"" AND 2 = a.""Click"" OR a.""Click"" > 10)))", t2);
 | 
			
		||||
 | 
			
		||||
            var aa03 = new[] {
 | 
			
		||||
                new ArrayAny02 { Name1 = "name01", Click1 = 1 },
 | 
			
		||||
@@ -44,7 +44,7 @@ WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name
 | 
			
		||||
            var t3 = fsql.Select<ArrayAny01>().Where(a => aa03.Any(b => b.Name1 == a.Name && b.Click1 == a.Click || a.Click > 10)).ToSql();
 | 
			
		||||
            Assert.Equal(@"SELECT a.""Id"", a.""Name"", a.""Click"" 
 | 
			
		||||
FROM ""ArrayAny01"" a 
 | 
			
		||||
WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10))", t3);
 | 
			
		||||
WHERE ((('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10)))", t3);
 | 
			
		||||
 | 
			
		||||
            var aa04 = new[] {
 | 
			
		||||
                new ArrayAny02 { Name1 = "name01", Click1 = 1 },
 | 
			
		||||
@@ -53,7 +53,7 @@ WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10))", t3);
 | 
			
		||||
            var t4 = fsql.Select<ArrayAny01>().Where(a => aa04.Any(b => b.Name1 == a.Name && b.Click1 == a.Click || a.Click > 10)).ToSql();
 | 
			
		||||
            Assert.Equal(@"SELECT a.""Id"", a.""Name"", a.""Click"" 
 | 
			
		||||
FROM ""ArrayAny01"" a 
 | 
			
		||||
WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name02' = a.""Name"" AND 2 = a.""Click"" OR a.""Click"" > 10))", t4);
 | 
			
		||||
WHERE ((('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name02' = a.""Name"" AND 2 = a.""Click"" OR a.""Click"" > 10)))", t4);
 | 
			
		||||
 | 
			
		||||
            // List
 | 
			
		||||
 | 
			
		||||
@@ -63,7 +63,7 @@ WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name
 | 
			
		||||
            var t5 = fsql.Select<ArrayAny01>().Where(a => aa05.Any(b => b.Name1 == a.Name && b.Click1 == a.Click || a.Click > 10)).ToSql();
 | 
			
		||||
            Assert.Equal(@"SELECT a.""Id"", a.""Name"", a.""Click"" 
 | 
			
		||||
FROM ""ArrayAny01"" a 
 | 
			
		||||
WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10))", t5);
 | 
			
		||||
WHERE ((('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10)))", t5);
 | 
			
		||||
 | 
			
		||||
            var aa06 = new List<ArrayAny02> {
 | 
			
		||||
                new ArrayAny02 { Name1 = "name01", Click1 = 1 },
 | 
			
		||||
@@ -72,7 +72,7 @@ WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10))", t5);
 | 
			
		||||
            var t6 = fsql.Select<ArrayAny01>().Where(a => aa06.Any(b => b.Name1 == a.Name && b.Click1 == a.Click || a.Click > 10)).ToSql();
 | 
			
		||||
            Assert.Equal(@"SELECT a.""Id"", a.""Name"", a.""Click"" 
 | 
			
		||||
FROM ""ArrayAny01"" a 
 | 
			
		||||
WHERE (('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name02' = a.""Name"" AND 2 = a.""Click"" OR a.""Click"" > 10))", t6);
 | 
			
		||||
WHERE ((('name01' = a.""Name"" AND 1 = a.""Click"" OR a.""Click"" > 10) OR ('name02' = a.""Name"" AND 2 = a.""Click"" OR a.""Click"" > 10)))", t6);
 | 
			
		||||
        }
 | 
			
		||||
        class ArrayAny01
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -328,28 +328,32 @@ namespace FreeSql.Internal
 | 
			
		||||
                            {
 | 
			
		||||
                                if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (diymemexp != null && dtTb.Parameter != null && dtTb.Parameter.Type.GetPropertiesDictIgnoreCase().TryGetValue(dtoProp.Name, out var dtTbProp))
 | 
			
		||||
                                    if (diymemexp != null && dtTb.Parameter != null)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        var dbfield = diymemexp.ParseExp(new Expression[] { Expression.MakeMemberAccess(dtTb.Parameter, dtTbProp) });
 | 
			
		||||
                                        if (diymemexp.ParseExpMapResult != null)
 | 
			
		||||
                                        var dbTbExp = MatchDtoProperty(dtTb, dtoProp);
 | 
			
		||||
                                        if (dbTbExp?.Any() == true)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            var diychild = new ReadAnonymousTypeInfo
 | 
			
		||||
                                            var dbfield = diymemexp.ParseExp(dbTbExp);
 | 
			
		||||
                                            if (diymemexp.ParseExpMapResult != null)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                Property = dtoProp,
 | 
			
		||||
                                                CsName = dtoProp.Name,
 | 
			
		||||
                                                CsType = dtTbProp.PropertyType,
 | 
			
		||||
                                                MapType = dtTbProp.PropertyType
 | 
			
		||||
                                            };
 | 
			
		||||
                                            parent.Childs.Add(diychild);
 | 
			
		||||
                                            diychild.DbField = $"{dtTb.Alias}.{diymemexp.ParseExpMapResult.DbNestedField}";
 | 
			
		||||
                                            diychild.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField;
 | 
			
		||||
                                            field.Append(", ").Append(diychild.DbField);
 | 
			
		||||
                                            if (index >= 0)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                diychild.DbNestedField = $"as{++index}";
 | 
			
		||||
                                                field.Append(_common.FieldAsAlias(diychild.DbNestedField));
 | 
			
		||||
                                                var diychild = new ReadAnonymousTypeInfo
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    Property = dtoProp,
 | 
			
		||||
                                                    CsName = dtoProp.Name,
 | 
			
		||||
                                                    CsType = dbTbExp.LastOrDefault().Type,
 | 
			
		||||
                                                    MapType = dbTbExp.LastOrDefault().Type
 | 
			
		||||
                                                };
 | 
			
		||||
                                                parent.Childs.Add(diychild);
 | 
			
		||||
                                                diychild.DbField = $"{dtTb.Alias}.{diymemexp.ParseExpMapResult.DbNestedField}";
 | 
			
		||||
                                                diychild.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField;
 | 
			
		||||
                                                field.Append(", ").Append(diychild.DbField);
 | 
			
		||||
                                                if (index >= 0)
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    diychild.DbNestedField = $"as{++index}";
 | 
			
		||||
                                                    field.Append(_common.FieldAsAlias(diychild.DbNestedField));
 | 
			
		||||
                                                }
 | 
			
		||||
                                                break;
 | 
			
		||||
                                            }
 | 
			
		||||
                                            break;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    continue;
 | 
			
		||||
@@ -450,28 +454,32 @@ namespace FreeSql.Internal
 | 
			
		||||
                            {
 | 
			
		||||
                                if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (diymemexp != null && dtTb.Parameter != null && dtTb.Parameter.Type.GetPropertiesDictIgnoreCase().TryGetValue(dtoProp.Name, out var dtTbProp))
 | 
			
		||||
                                    if (diymemexp != null && dtTb.Parameter != null)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        var dbfield = diymemexp.ParseExp(new Expression[] { Expression.MakeMemberAccess(dtTb.Parameter, dtTbProp) });
 | 
			
		||||
                                        if (diymemexp.ParseExpMapResult != null)
 | 
			
		||||
                                        var dbTbExp = MatchDtoProperty(dtTb, dtoProp);
 | 
			
		||||
                                        if (dbTbExp?.Any() == true)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            var diychild = new ReadAnonymousTypeInfo
 | 
			
		||||
                                            var dbfield = diymemexp.ParseExp(dbTbExp);
 | 
			
		||||
                                            if (diymemexp.ParseExpMapResult != null)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                Property = dtoProp,
 | 
			
		||||
                                                CsName = dtoProp.Name,
 | 
			
		||||
                                                CsType = dtTbProp.PropertyType,
 | 
			
		||||
                                                MapType = dtTbProp.PropertyType
 | 
			
		||||
                                            };
 | 
			
		||||
                                            parent.Childs.Add(diychild);
 | 
			
		||||
                                            diychild.DbField = $"{dtTb.Alias}.{diymemexp.ParseExpMapResult.DbNestedField}";
 | 
			
		||||
                                            diychild.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField;
 | 
			
		||||
                                            field.Append(", ").Append(diychild.DbField);
 | 
			
		||||
                                            if (index >= 0)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                diychild.DbNestedField = $"as{++index}";
 | 
			
		||||
                                                field.Append(_common.FieldAsAlias(diychild.DbNestedField));
 | 
			
		||||
                                                var diychild = new ReadAnonymousTypeInfo
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    Property = dtoProp,
 | 
			
		||||
                                                    CsName = dtoProp.Name,
 | 
			
		||||
                                                    CsType = dbTbExp.LastOrDefault().Type,
 | 
			
		||||
                                                    MapType = dbTbExp.LastOrDefault().Type
 | 
			
		||||
                                                };
 | 
			
		||||
                                                parent.Childs.Add(diychild);
 | 
			
		||||
                                                diychild.DbField = $"{dtTb.Alias}.{diymemexp.ParseExpMapResult.DbNestedField}";
 | 
			
		||||
                                                diychild.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField;
 | 
			
		||||
                                                field.Append(", ").Append(diychild.DbField);
 | 
			
		||||
                                                if (index >= 0)
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    diychild.DbNestedField = $"as{++index}";
 | 
			
		||||
                                                    field.Append(_common.FieldAsAlias(diychild.DbNestedField));
 | 
			
		||||
                                                }
 | 
			
		||||
                                                break;
 | 
			
		||||
                                            }
 | 
			
		||||
                                            break;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    continue;
 | 
			
		||||
@@ -1723,7 +1731,7 @@ namespace FreeSql.Internal
 | 
			
		||||
                                        expStack.Push(oper2Parm);
 | 
			
		||||
                                    else if (oper2Parm.Type != typeof(object) && oper2Parm.Type.IsAssignableFrom(exp2.Type))
 | 
			
		||||
                                        expStack.Push(oper2Parm);
 | 
			
		||||
                                    else if (oper2Parm.Type == typeof(object) && tsc._tables[0].Table != null && exp2.Type.IsAssignableFrom(tsc._tables[0].Table.Type) == true)
 | 
			
		||||
                                    else if (oper2Parm.Type == typeof(object) && tsc._tables != null && tsc._tables[0].Table != null && exp2.Type.IsAssignableFrom(tsc._tables[0].Table.Type) == true)
 | 
			
		||||
                                        expStack.Push(oper2Parm);
 | 
			
		||||
                                    else
 | 
			
		||||
                                        expStack.Push(Expression.Parameter(exp2.Type, oper2Parm.Name));
 | 
			
		||||
@@ -2490,6 +2498,40 @@ namespace FreeSql.Internal
 | 
			
		||||
            //return string.Concat(_ado.AddslashesProcessParam(obj, mapType, mapColumn));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Expression[] MatchDtoProperty(SelectTableInfo tb, PropertyInfo dtoProp)
 | 
			
		||||
        {
 | 
			
		||||
            if (tb == null || dtoProp == null || tb.Parameter == null) return null;
 | 
			
		||||
            var exp = LocalMatch(tb.Parameter.Type, tb.Parameter);
 | 
			
		||||
            if (exp == null) return null;
 | 
			
		||||
            var exps = new Stack<Expression>();
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                exps.Push(exp);
 | 
			
		||||
                exp = (exp as MemberExpression).Expression;
 | 
			
		||||
                if (exp.NodeType == ExpressionType.Parameter) break;
 | 
			
		||||
            }
 | 
			
		||||
            if (exps.Any()) return exps.ToArray();
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
            Expression LocalMatch(Type type, Expression memExp)
 | 
			
		||||
            {
 | 
			
		||||
                var typeProps = type.GetPropertiesDictIgnoreCase();
 | 
			
		||||
                if (typeProps.TryGetValue(dtoProp.Name, out var prop))
 | 
			
		||||
                    return Expression.MakeMemberAccess(memExp, prop);
 | 
			
		||||
                if (tb.Table.Columns.Any() == false) //匿名类,嵌套查询 DTO
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var typeProp in typeProps.Values)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(type)) return null;
 | 
			
		||||
                        var nextExp = Expression.MakeMemberAccess(memExp, typeProp);
 | 
			
		||||
                        var ret = LocalMatch(typeProp.PropertyType, nextExp);
 | 
			
		||||
                        if (ret != null) return ret;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void ParseExpressionNoAsSelect(object sender, Aop.ParseExpressionEventArgs e, Func<Type, string, string> tableRule, List<GlobalFilter.Item> whereGlobalFilter)
 | 
			
		||||
        {
 | 
			
		||||
            if (e.Expression.NodeType != ExpressionType.Call &&
 | 
			
		||||
 
 | 
			
		||||
@@ -655,11 +655,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            if (col.Attribute.MapType == col.CsType) val = value;
 | 
			
		||||
            else val = Utils.GetDataReaderValue(col.Attribute.MapType, value);
 | 
			
		||||
            _set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ");
 | 
			
		||||
            if (value == null)
 | 
			
		||||
            {
 | 
			
		||||
                _set.Append("NULL");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(_params, "u", col, col.Attribute.MapType, val) :
 | 
			
		||||
                _commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_params.Count}"));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user