diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 777375a4..2764225a 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -757,9 +757,29 @@ namespace FreeSql.Tests.Sqlite { Assert.Equal("SELECT a.\"Id\", a.\"Clicks\", a.\"TypeGuid\", a.\"Title\", a.\"CreateTime\" FROM \"tb_topic22AsTable1\" a LEFT JOIN \"TestTypeInfo\" b on b.\"Guid\" = a.\"TypeGuid\" and b.\"Name\" = @bname", sql); } + class TestInclude_OneToManyModel1 { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + } + class TestInclude_OneToManyModel2 { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel2 model1 { get; set; } + + public virtual List childs { get; set; } + } + class TestInclude_OneToManyModel3 { + [Column(IsIdentity = true)] + public int id { get; set; } + + public string title { get; set; } + } + [Fact] public void Include_OneToMany() { - + var model1 = new TestInclude_OneToManyModel1 { }; + model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity(); } [Fact] public void Include_OneToChilds() { @@ -891,6 +911,12 @@ namespace FreeSql.Tests.Sqlite { Assert.Equal(2, songs2[0].Tags.Count); Assert.Equal(1, songs2[1].Tags.Count); Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.sqlite.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); } } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index edefa288..72f7aa00 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -352,8 +352,11 @@ namespace FreeSql.Internal.CommonProvider { if (tb == null) throw throwNavigateSelector; var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate)); if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany"); - TableRef tbref = null; + if (collMem.Expression.NodeType != ExpressionType.Parameter) + _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); + + TableRef tbref = null; if (whereExp == null) { tbref = tb.GetTableRef(collMem.Member.Name, true); @@ -383,19 +386,27 @@ namespace FreeSql.Internal.CommonProvider { var leftP1MemberExp = binaryExp.Left as MemberExpression; var rightP1MemberExp = binaryExp.Right as MemberExpression; if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector; - if (leftP1MemberExp.Expression != tmpExp && leftP1MemberExp.Expression != whereExpArgLamb.Parameters[0] || - rightP1MemberExp.Expression != tmpExp && rightP1MemberExp.Expression != whereExpArgLamb.Parameters[0]) throw throwNavigateSelector; - if (leftP1MemberExp.Expression == tmpExp && rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { - tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]); - tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]); - return; - } - if (rightP1MemberExp.Expression == tmpExp && leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { + if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { + var rightParExp = rightP1MemberExp; + while (rightParExp.Expression != tmpExp) { + rightParExp = rightParExp.Expression as MemberExpression; + if (rightParExp == null) throw throwNavigateSelector; + } tbref.Columns.Add(tb.ColumnsByCs[rightP1MemberExp.Member.Name]); tbref.RefColumns.Add(tbNav.ColumnsByCs[leftP1MemberExp.Member.Name]); return; } + if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) { + var leftParExp = leftP1MemberExp; + while (leftParExp.Expression != tmpExp) { + leftParExp = leftParExp.Expression as MemberExpression; + if (leftParExp == null) throw throwNavigateSelector; + } + tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]); + tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]); + return; + } throw throwNavigateSelector; default: throw throwNavigateSelector; @@ -407,9 +418,6 @@ namespace FreeSql.Internal.CommonProvider { if (tbref.Columns.Any() == false) throw throwNavigateSelector; } - if (collMem.Expression.NodeType != ExpressionType.Parameter) - _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null); - _includeToList.Enqueue(listObj => { var list = listObj as List; if (list == null) return; @@ -448,7 +456,9 @@ 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))).Distinct().ToArray()); + var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, + list.Select(a => getListValue(a, tbref.Columns[0].CsName)).Distinct() + .Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).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);