diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 7b687258..3cb9aa53 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -227,9 +227,41 @@ namespace FreeSql.Tests public decimal rowstate { get; set; } } + public class otot1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + + public otot2 t2 { get; set; } + } + public class otot2 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + } + [Fact] public void Test02() { + g.sqlite.Insert(new otot1 { name = "otot1_name1" }).ExecuteAffrows(); + + var otolst1 = g.sqlite.Select() + .LeftJoin(a => a.id == a.t2.id) + .ToList(); + + var otolst2 = g.sqlite.Select() + .LeftJoin((a, b) => a.id == b.id) + .ToList((a, b) => new + { + a, + b + }); + + + + var testcf = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(dfDto2), "main.test2"); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index b8fdfa9c..e7d7bd56 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -80,6 +80,7 @@ namespace FreeSql.Internal var tb = parent.Table = map.First().Table.Table; parent.Consturctor = tb.Type.GetConstructor(new Type[0]); parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; + parent.IsEntity = true; for (var idx = 0; idx < map.Count; idx++) { var child = new ReadAnonymousTypeInfo @@ -220,7 +221,7 @@ namespace FreeSql.Internal if (index >= 0) field.Append(" as").Append(++index); return false; } - public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) + public object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead, ReadAnonymousDbValueRef dbValue) { if (parent.Childs.Any() == false) { @@ -232,6 +233,7 @@ namespace FreeSql.Internal return Utils.GetDataReaderValue(parent.CsType, null); } object objval = dr.GetValue(++index); + if (dbValue != null) dbValue.DbValue = objval == DBNull.Value ? null : objval; if (parent.CsType != parent.MapType) objval = Utils.GetDataReaderValue(parent.MapType, objval); objval = Utils.GetDataReaderValue(parent.CsType, objval); @@ -245,7 +247,7 @@ namespace FreeSql.Internal var args = new object[parent.Childs.Count]; for (var a = 0; a < parent.Childs.Count; a++) { - var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead); + var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead, null); if (notRead == false) args[a] = objval; } @@ -256,8 +258,9 @@ namespace FreeSql.Internal for (var b = 0; b < parent.Childs.Count; b++) { var prop = parent.Childs[b].Property; - var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead); - if (isnull == false && objval == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) + var dbval = parent.IsEntity ? new ReadAnonymousDbValueRef() : null; + var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead, dbval); + if (isnull == false && parent.IsEntity && dbval.DbValue == null && parent.Table != null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary) isnull = true; if (isnull == false && prop.CanWrite) prop.SetValue(ret, objval, null); @@ -266,6 +269,10 @@ namespace FreeSql.Internal } return null; } + public class ReadAnonymousDbValueRef + { + public object DbValue { get; set; } + } public ColumnInfo SearchColumnByField(List _tables, TableInfo currentTable, string field) { diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 2a3e034c..ad4c1ee6 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -352,7 +352,7 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); } }, CommandType.Text, sql, dbParms); } @@ -405,7 +405,7 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); } if (chunkSize > 0 && chunkSize == ret.Count) { @@ -487,10 +487,10 @@ namespace FreeSql.Internal.CommonProvider _orm.Ado.ExecuteReader(_connection, _transaction, dr => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); }, CommandType.Text, sql, dbParms); } catch (Exception ex) @@ -1151,7 +1151,7 @@ namespace FreeSql.Internal.CommonProvider { var idx = af.FieldCount - 1; foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref idx, false, null)); } return Task.FromResult(false); }, CommandType.Text, sql, dbParms); @@ -1214,10 +1214,10 @@ namespace FreeSql.Internal.CommonProvider await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, dr => { var index = -1; - ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false)); + ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false, null)); if (otherData != null) foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false)); + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, dr, ref index, false, null)); return Task.FromResult(false); }, CommandType.Text, sql, dbParms); } diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index d3c1fb3a..3ca01e00 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -16,6 +16,7 @@ namespace FreeSql.Internal.Model public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } public List Childs = new List(); public TableInfo Table { get; set; } + public bool IsEntity { get; set; } } public enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties } }