mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	IncludeMany 非导航加载,支持多级
This commit is contained in:
		@@ -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<TestInclude_OneToManyModel3> 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<Song_tag>()
 | 
			
		||||
				.Include(a => a.Tag.Parent)
 | 
			
		||||
				.IncludeMany(a => a.Tag.Songs)
 | 
			
		||||
				.Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id)
 | 
			
		||||
				.ToList(true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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 (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
 | 
			
		||||
									var rightParExp = rightP1MemberExp;
 | 
			
		||||
									while (rightParExp.Expression != tmpExp) {
 | 
			
		||||
										rightParExp = rightParExp.Expression as MemberExpression;
 | 
			
		||||
										if (rightParExp == null) throw throwNavigateSelector;
 | 
			
		||||
									}
 | 
			
		||||
								if (rightP1MemberExp.Expression == tmpExp && leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
 | 
			
		||||
									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<T1>;
 | 
			
		||||
				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<string, MethodInfo>()).GetOrAdd("Contains", mn =>
 | 
			
		||||
									typeof(Enumerable).GetMethods().Where(a => a.Name == mn).First()).MakeGenericMethod(tbref.Columns[0].CsType);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user