Skip to content

Commit fe016c0

Browse files
2881028810
authored andcommitted
IncludeMany 非导航加载,支持多级
1 parent defaa22 commit fe016c0

File tree

2 files changed

+50
-14
lines changed

2 files changed

+50
-14
lines changed

FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,9 +757,29 @@ public void AsTable() {
757757
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);
758758
}
759759

760+
class TestInclude_OneToManyModel1 {
761+
[Column(IsIdentity = true)]
762+
public int id { get; set; }
763+
public virtual TestInclude_OneToManyModel2 model2 { get; set; }
764+
}
765+
class TestInclude_OneToManyModel2 {
766+
[Column(IsPrimary = true)]
767+
public int model2id { get; set; }
768+
public virtual TestInclude_OneToManyModel2 model1 { get; set; }
769+
770+
public virtual List<TestInclude_OneToManyModel3> childs { get; set; }
771+
}
772+
class TestInclude_OneToManyModel3 {
773+
[Column(IsIdentity = true)]
774+
public int id { get; set; }
775+
776+
public string title { get; set; }
777+
}
778+
760779
[Fact]
761780
public void Include_OneToMany() {
762-
781+
var model1 = new TestInclude_OneToManyModel1 { };
782+
model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity();
763783
}
764784
[Fact]
765785
public void Include_OneToChilds() {
@@ -891,6 +911,12 @@ public void Include_ManyToMany() {
891911
Assert.Equal(2, songs2[0].Tags.Count);
892912
Assert.Equal(1, songs2[1].Tags.Count);
893913
Assert.Equal(3, songs2[2].Tags.Count);
914+
915+
var tags3 = g.sqlite.Select<Song_tag>()
916+
.Include(a => a.Tag.Parent)
917+
.IncludeMany(a => a.Tag.Songs)
918+
.Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id)
919+
.ToList(true);
894920
}
895921
}
896922
}

FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,11 @@ public ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavig
352352
if (tb == null) throw throwNavigateSelector;
353353
var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate));
354354
if (tbNav == null) throw new Exception($"类型 {typeof(TNavigate).FullName} 错误,不能使用 IncludeMany");
355-
TableRef tbref = null;
356355

356+
if (collMem.Expression.NodeType != ExpressionType.Parameter)
357+
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
358+
359+
TableRef tbref = null;
357360
if (whereExp == null) {
358361

359362
tbref = tb.GetTableRef(collMem.Member.Name, true);
@@ -383,19 +386,27 @@ public ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavig
383386
var leftP1MemberExp = binaryExp.Left as MemberExpression;
384387
var rightP1MemberExp = binaryExp.Right as MemberExpression;
385388
if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector;
386-
if (leftP1MemberExp.Expression != tmpExp && leftP1MemberExp.Expression != whereExpArgLamb.Parameters[0] ||
387-
rightP1MemberExp.Expression != tmpExp && rightP1MemberExp.Expression != whereExpArgLamb.Parameters[0]) throw throwNavigateSelector;
388389

389-
if (leftP1MemberExp.Expression == tmpExp && rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
390-
tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]);
391-
tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]);
392-
return;
393-
}
394-
if (rightP1MemberExp.Expression == tmpExp && leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
390+
if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
391+
var rightParExp = rightP1MemberExp;
392+
while (rightParExp.Expression != tmpExp) {
393+
rightParExp = rightParExp.Expression as MemberExpression;
394+
if (rightParExp == null) throw throwNavigateSelector;
395+
}
395396
tbref.Columns.Add(tb.ColumnsByCs[rightP1MemberExp.Member.Name]);
396397
tbref.RefColumns.Add(tbNav.ColumnsByCs[leftP1MemberExp.Member.Name]);
397398
return;
398399
}
400+
if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
401+
var leftParExp = leftP1MemberExp;
402+
while (leftParExp.Expression != tmpExp) {
403+
leftParExp = leftParExp.Expression as MemberExpression;
404+
if (leftParExp == null) throw throwNavigateSelector;
405+
}
406+
tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]);
407+
tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]);
408+
return;
409+
}
399410

400411
throw throwNavigateSelector;
401412
default: throw throwNavigateSelector;
@@ -407,9 +418,6 @@ public ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavig
407418
if (tbref.Columns.Any() == false) throw throwNavigateSelector;
408419
}
409420

410-
if (collMem.Expression.NodeType != ExpressionType.Parameter)
411-
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
412-
413421
_includeToList.Enqueue(listObj => {
414422
var list = listObj as List<T1>;
415423
if (list == null) return;
@@ -448,7 +456,9 @@ public ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavig
448456
if (true) {
449457
var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
450458
if (tbref.Columns.Count == 1) {
451-
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());
459+
var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType,
460+
list.Select(a => getListValue(a, tbref.Columns[0].CsName)).Distinct()
461+
.Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).ToArray());
452462
var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
453463
var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
454464
typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType);

0 commit comments

Comments
 (0)