diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 594fbad3..537315e2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -733,6 +733,15 @@ + + + 根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类 + + + + + + 创建普通数据上下文档对象 diff --git a/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs b/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs index f0f8d824..ffcbfd69 100644 --- a/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Internal/UtilsTest.cs @@ -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 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; }; diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs index 2294ab2f..08ca5d12 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs @@ -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() + .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() + .FromQuery(lpsPgi) + .InnerJoin((a, b) => a.SeqNoLog == b.SeqNoLog) + .WithTempQuery((a, b) => new { Item1 = a, Item2 = b }) + .From() + .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(); 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(); 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(); 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(); 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() @@ -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(); 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() diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs index 7ecc7341..0a02aadf 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs @@ -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().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().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().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().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 { 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().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 { diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index ba4ded16..2dfda1a8 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -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(); + 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 tableRule, List whereGlobalFilter) { if (e.Expression.NodeType != ExpressionType.Call && diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 9117e0c6..5e786eff 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -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}"));