From dbfc33fef5a2062f64d0b22d693f919f0f2fc6ca Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 11 May 2019 17:07:24 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20IncludeMany=20ManyToMa?= =?UTF-8?q?ny=20ET=20=E7=BC=93=E5=AD=98=E7=9A=84=20bug=EF=BC=9B=20-=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84=20IncludeMany=20=E8=81=94=E5=90=88=E9=94=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=9B=20-=20=E5=AE=8C=E5=96=84=20Include/?= =?UTF-8?q?IncludeMany=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=9B=20-?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=20Include=20=E5=BB=B6=E6=97=B6=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=20ManyToOne/OneToOne=EF=BC=8C=E5=BD=93=E5=80=BC?= =?UTF-8?q?=E4=B8=BA=20null=20=E6=97=B6=EF=BC=8C=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E4=BC=9A=E6=9F=A5=E8=AF=A2=E4=B8=80=E6=AC=A1=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs | 77 ++++++++++++++++ FreeSql/FreeSql.csproj | 2 +- .../SelectProvider/Select0Provider.cs | 91 ++++++++++++------- .../SelectProvider/Select1Provider.cs | 76 ++++++++++------ FreeSql/Internal/UtilsExpressionTree.cs | 5 +- 5 files changed, 190 insertions(+), 61 deletions(-) diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 6fbc87da..777375a4 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -763,7 +763,69 @@ namespace FreeSql.Tests.Sqlite { } [Fact] public void Include_OneToChilds() { + var tag1 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.sqlite.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.sqlite.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.sqlite.Insert(tag1_2).ExecuteIdentity(); + var tag2 = new Tag { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.sqlite.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.sqlite.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.sqlite.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.sqlite.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags = g.sqlite.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); } [Fact] @@ -813,7 +875,22 @@ namespace FreeSql.Tests.Sqlite { var songs = g.sqlite.Select() .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) .ToList(); + Assert.Equal(3, songs.Count); + Assert.Equal(2, songs[0].Tags.Count); + Assert.Equal(1, songs[1].Tags.Count); + Assert.Equal(3, songs[2].Tags.Count); + + var songs2 = g.sqlite.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); } } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 84f52154..f066981b 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.5.13 + 0.5.14 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 08c4da0c..b8445add 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -286,8 +286,6 @@ namespace FreeSql.Internal.CommonProvider { var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); return ret; }); } @@ -315,13 +313,18 @@ namespace FreeSql.Internal.CommonProvider { var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfter?.Invoke(this, after); } - _orm.Aop.ToList?.Invoke(this, new Aop.ToListEventArgs(ret)); - _trackToList?.Invoke(ret); return ret; }); } - internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, (ReadAnonymousTypeInfo, List)[] otherData) { - var sql = this.ToSql(af.Field); + internal List ToListPrivate(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { + string sql = null; + if (otherData?.Length > 0) { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } else + sql = this.ToSql(af.Field); if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { @@ -336,7 +339,7 @@ namespace FreeSql.Internal.CommonProvider { if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.Item2.Add(_commonExpression.ReadAnonymous(other.Item1, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); } }, CommandType.Text, sql, dbParms); } catch (Exception ex) { @@ -352,8 +355,15 @@ namespace FreeSql.Internal.CommonProvider { return ret; }); } - async internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (ReadAnonymousTypeInfo, List)[] otherData) { - var sql = this.ToSql(af.Field); + async internal Task> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, (string field, ReadAnonymousTypeInfo read, List retlist)[] otherData) { + string sql = null; + if (otherData?.Length > 0) { + var sbField = new StringBuilder().Append(af.Field); + foreach (var other in otherData) + sbField.Append(other.field); + sql = this.ToSql(sbField.ToString()); + } else + sql = this.ToSql(af.Field); if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { @@ -368,7 +378,7 @@ namespace FreeSql.Internal.CommonProvider { if (otherData != null) { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.Item2.Add(_commonExpression.ReadAnonymous(other.Item1, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); } return Task.CompletedTask; }, CommandType.Text, sql, dbParms); @@ -501,13 +511,30 @@ namespace FreeSql.Internal.CommonProvider { var tb = _tables.First(); var index = 0; + var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias)); var tbiindex = 0; - foreach (var tbi in _tables.ToArray().OrderBy(a => a.Alias)) { + foreach (var tbi in tborder) { if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue; if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue; var typei = tbi.Table.TypeLazy ?? tbi.Table.Type; Expression curExp = retExp; + + var colidx = 0; + foreach (var col in tbi.Table.Columns.Values) { + if (index > 0) { + field.Append(", "); + if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); + } + var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); + field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); + ++index; + if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); + else dicfield.Add(quoteName, true); + ++colidx; + } + tbiindex++; + if (tbiindex == 0) blockExp.AddRange(new Expression[] { Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), @@ -547,7 +574,7 @@ namespace FreeSql.Internal.CommonProvider { if (iscontinue) continue; blockExp.Add( - Expression.IfThen( + Expression.IfThenElse( curExpIfNotNull, Expression.Block(new Expression[] { Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })), @@ -555,11 +582,16 @@ namespace FreeSql.Internal.CommonProvider { Expression.GreaterThan(readExpDataIndex, dataIndexExp), Expression.Assign(dataIndexExp, readExpDataIndex) ), - Expression.IfThen( + Expression.IfThenElse( Expression.NotEqual(readExpValue, Expression.Constant(null)), - Expression.Assign(curExp, Expression.Convert(readExpValue, typei)) + Expression.Assign(curExp, Expression.Convert(readExpValue, typei)), + Expression.Assign(curExp, Expression.Constant(null, typei)) ) - }) + }), + Expression.Block( + Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))), + Expression.Assign(dataIndexExp, Expression.Constant(index)) + ) ) ); } @@ -571,21 +603,6 @@ namespace FreeSql.Internal.CommonProvider { Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp) ) ); //将 orm 传递给 lazy - - var colidx = 0; - foreach (var col in tbi.Table.Columns.Values) { - if (index > 0) { - field.Append(", "); - if (tbiindex > 0 && colidx == 0) field.Append("\r\n"); - } - var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name); - field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}")); - ++index; - if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index); - else dicfield.Add(quoteName, true); - ++colidx; - } - tbiindex++; } blockExp.AddRange(new Expression[] { @@ -685,9 +702,17 @@ namespace FreeSql.Internal.CommonProvider { Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), Expression.Assign(dataIndexExp, readExpDataIndex)), //Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)), - Expression.IfThen(Expression.NotEqual(readExpValue, Expression.Constant(null)), - //Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)), - Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))) + + tb1.TypeLazy != null ? + Expression.IfThenElse( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType)) + ) : + Expression.IfThen( + Expression.NotEqual(readExpValue, Expression.Constant(null)), + Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)) + ) }); } if (otherindex == 0) { //不读导航属性,优化单表读取性能 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 242c304b..e9a8ff8e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -343,13 +343,15 @@ namespace FreeSql.Internal.CommonProvider { if (collMem.Expression.NodeType != ExpressionType.Parameter) _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); - var tbref = tb.GetTableRef(collMem.Member.Name, true); _includeToList.Enqueue(listObj => { var list = listObj as List; if (list == null) return; if (list.Any() == false) return; + var tbref = tb.GetTableRef(collMem.Member.Name, true); + if (tbref.Columns.Any() == false) return; + var t1parm = Expression.Parameter(typeof(T1)); Expression membersExp = t1parm; while (members.Any()) membersExp = Expression.MakeMemberAccess(membersExp, members.Pop()); @@ -381,7 +383,7 @@ namespace FreeSql.Internal.CommonProvider { if (true) { var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType); if (tbref.Columns.Count == 1) { - var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, list.Select(a => Expression.Constant(Convert.ChangeType(getListValue(a, tbref.Columns[0].CsName), tbref.Columns[0].CsType))).ToArray()); + var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, list.Select(a => Expression.Constant(Convert.ChangeType(getListValue(a, tbref.Columns[0].CsName), tbref.Columns[0].CsType))).Distinct().ToArray()); var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a"); var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary()).GetOrAdd("Contains", mn => typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType); @@ -466,21 +468,34 @@ namespace FreeSql.Internal.CommonProvider { if (true) { var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType); var tbrefMid = _commonUtils.GetTableByEntity(tbref.RefMiddleEntityType); + var sbJoin = new StringBuilder().Append($"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON"); + for (var z = 0; z < tbref.RefColumns.Count; z++) { + if (z > 0) sbJoin.Append(" AND"); + sbJoin.Append($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[tbref.Columns.Count + z].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}"); + } + subSelect.InnerJoin(sbJoin.ToString()); + sbJoin.Clear(); if (tbref.Columns.Count == 1) { - //var midParmExp = Expression.Parameter(tbref.RefMiddleEntityType, "midtb"); - //(subSelect as Select1Provider)._tables.Add(new SelectTableInfo { - // Alias = "midtb", - // AliasInit = "midtb", - // On = $"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[1].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)}", - // Parameter = midParmExp, - // Table = tbrefMid, - // Type = SelectTableInfoType.InnerJoin - //}); - subSelect.InnerJoin($"{_commonUtils.QuoteSqlName(tbrefMid.DbName)} midtb ON midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[1].Attribute.Name)} = a.{_commonUtils.QuoteSqlName(tbref.RefColumns[0].Attribute.Name)}"); - subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue(a, tbref.Columns[0].CsName)))); - + subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue(a, tbref.Columns[0].CsName)).Distinct())); } else { - + Dictionary sbDic = new Dictionary(); + for (var y = 0; y < list.Count; y++) { + var sbWhereOne = new StringBuilder(); + sbWhereOne.Append(" ("); + for (var z = 0; z < tbref.Columns.Count; z++) { + if (z > 0) sbWhereOne.Append(" AND"); + sbWhereOne.Append(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName))); + } + sbWhereOne.Append(")"); + var whereOne = sbWhereOne.ToString(); + sbWhereOne.Clear(); + if (sbDic.ContainsKey(whereOne) == false) sbDic.Add(whereOne, true); + } + var sbWhere = new StringBuilder(); + foreach (var sbd in sbDic) + sbWhere.Append(" OR").Append(sbd.Key); + subSelect.Where(sbWhere.Remove(0, 3).ToString()); + sbWhere.Clear(); } then?.Invoke(subSelect); @@ -490,7 +505,7 @@ namespace FreeSql.Internal.CommonProvider { var subSelectP1 = (subSelect as Select1Provider); var af = subSelectP1.GetAllFieldExpressionTreeLevelAll(); if (_selectExpression == null) {// return this.InternalToList(_selectExpression).Select(a => (a, ()).ToList(); - var sb = new StringBuilder().Append(af.Field); + var field = new StringBuilder(); var read = new ReadAnonymousTypeInfo(); read.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; read.Consturctor = tbrefMid.TypeLazy.GetConstructor(new Type[0]); @@ -505,10 +520,9 @@ namespace FreeSql.Internal.CommonProvider { Property = tbrefMid.Properties[col.CsName] }; read.Childs.Add(child); - sb.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField)); + field.Append(", ").Append(_commonUtils.QuoteReadColumn(child.MapType, child.DbField)); } - af.Field = sb.ToString(); - subList = subSelectP1.ToListPrivate(af, new[] { (read, midList) }); + subList = subSelectP1.ToListPrivate(af, new[] { (field.ToString(), read, midList) }); } else subList = subSelectP1.ToListPrivate(af, null); @@ -518,17 +532,25 @@ namespace FreeSql.Internal.CommonProvider { return; } - Dictionary>> dicList = new Dictionary>>(); + Dictionary>>> dicList = new Dictionary>>>(); foreach (var item in list) { if (tbref.Columns.Count == 1) { - dicList.Add(getListValue(item, tbref.Columns[0].CsName).ToString(), Tuple.Create(item, new List())); + var dicListKey = getListValue(item, tbref.Columns[0].CsName).ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); } else { var sb = new StringBuilder(); for (var z = 0; z < tbref.Columns.Count; z++) { if (z > 0) sb.Append("*$*"); sb.Append(getListValue(item, tbref.Columns[z].CsName)); } - dicList.Add(sb.Remove(0, 3).ToString(), Tuple.Create(item, new List())); + var dicListKey = sb.Remove(0, 3).ToString(); + var dicListVal = Tuple.Create(item, new List()); + if (dicList.TryGetValue(dicListKey, out var items) == false) + dicList.Add(dicListKey, items = new List>>()); + items.Add(dicListVal); sb.Clear(); } } @@ -545,11 +567,13 @@ namespace FreeSql.Internal.CommonProvider { key = sb.ToString(); sb.Clear(); } - if (dicList.TryGetValue(key, out var t1item) == false) return; - t1item.Item2.Add(subList[a]); + if (dicList.TryGetValue(key, out var t1items) == false) return; + foreach (var t1item in t1items) + t1item.Item2.Add(subList[a]); } - foreach (var t1item in dicList.Values) - setListValue(t1item.Item1, t1item.Item2); + foreach (var t1items in dicList.Values) + foreach (var t1item in t1items) + setListValue(t1item.Item1, t1item.Item2); dicList.Clear(); } break; diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 24dc24ac..dc57c71d 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -605,7 +605,10 @@ namespace FreeSql.Internal { .Append(" }\r\n"); } if (vp.Item3) { //set 重写 - cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;"); + cscode.Append(" set {\r\n") + .Append(" base.").Append(pnv.Name).AppendLine(" = value;") + .Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;") + .Append(" }\r\n"); } cscode.AppendLine(" }"); }