mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	解决变异的 IncludeMany 在多级使用时,无法使用上层的值映射
This commit is contained in:
		@@ -824,6 +824,53 @@ namespace FreeSql.Tests.Sqlite {
 | 
				
			|||||||
				.Where(a => a.id <= model1.id)
 | 
									.Where(a => a.id <= model1.id)
 | 
				
			||||||
				.ToList();
 | 
									.ToList();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public class TestInclude_OneToManyModel11 {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true)]
 | 
				
			||||||
 | 
								public int id { get; set; }
 | 
				
			||||||
 | 
								public int model2id { get; set; }
 | 
				
			||||||
 | 
								public string m3setting { get; set; }
 | 
				
			||||||
 | 
								public TestInclude_OneToManyModel22 model2 { get; set; }
 | 
				
			||||||
 | 
								public string m1name { get; set; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public class TestInclude_OneToManyModel22 {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true)]
 | 
				
			||||||
 | 
								public int id { get; set; }
 | 
				
			||||||
 | 
								public string m2setting { get; set; }
 | 
				
			||||||
 | 
								public List<TestInclude_OneToManyModel33> childs { get; set; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							public class TestInclude_OneToManyModel33 {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true)]
 | 
				
			||||||
 | 
								public int id { get; set; }
 | 
				
			||||||
 | 
								public int model2Id { get; set; }
 | 
				
			||||||
 | 
								public string title { get; set; }
 | 
				
			||||||
 | 
								public string setting { get; set; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							[Fact]
 | 
				
			||||||
 | 
							public void Include_OneToMany2() {
 | 
				
			||||||
 | 
								string setting = "x";
 | 
				
			||||||
 | 
								var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString() };
 | 
				
			||||||
 | 
								model2.id = (int)g.sqlite.Insert(model2).ExecuteIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var model3s = new[]
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting},
 | 
				
			||||||
 | 
									new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting},
 | 
				
			||||||
 | 
									new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting}
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								Assert.Equal(3, g.sqlite.Insert(model3s).ExecuteAffrows());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting };
 | 
				
			||||||
 | 
								model1.id = (int)g.sqlite.Insert(model1).ExecuteIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var t1 = g.sqlite.Select<TestInclude_OneToManyModel11>()
 | 
				
			||||||
 | 
									.LeftJoin(a => a.model2id == a.model2.id)
 | 
				
			||||||
 | 
									.IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting))
 | 
				
			||||||
 | 
									.Where(a => a.id == model1.id)
 | 
				
			||||||
 | 
									.ToList(true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void Include_OneToChilds() {
 | 
							public void Include_OneToChilds() {
 | 
				
			||||||
			var tag1 = new Tag {
 | 
								var tag1 = new Tag {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	<PropertyGroup>
 | 
						<PropertyGroup>
 | 
				
			||||||
		<TargetFramework>netstandard2.0</TargetFramework>
 | 
							<TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
		<Version>0.5.18</Version>
 | 
							<Version>0.5.19</Version>
 | 
				
			||||||
		<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
							<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
		<Authors>YeXiangQin</Authors>
 | 
							<Authors>YeXiangQin</Authors>
 | 
				
			||||||
		<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
 | 
							<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ using System;
 | 
				
			|||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -314,6 +315,29 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							static (ParameterExpression param, List<MemberExpression> members) GetExpressionStack(Expression exp) {
 | 
				
			||||||
 | 
								Expression tmpExp = exp;
 | 
				
			||||||
 | 
								ParameterExpression param = null;
 | 
				
			||||||
 | 
								var members = new List<MemberExpression>();
 | 
				
			||||||
 | 
								var isbreak = false;
 | 
				
			||||||
 | 
								while (isbreak == false) {
 | 
				
			||||||
 | 
									switch (tmpExp.NodeType) {
 | 
				
			||||||
 | 
										case ExpressionType.MemberAccess:
 | 
				
			||||||
 | 
											var memExp = tmpExp as MemberExpression;
 | 
				
			||||||
 | 
											tmpExp = memExp.Expression;
 | 
				
			||||||
 | 
											members.Add(memExp);
 | 
				
			||||||
 | 
											continue;
 | 
				
			||||||
 | 
										case ExpressionType.Parameter:
 | 
				
			||||||
 | 
											param = tmpExp as ParameterExpression;
 | 
				
			||||||
 | 
											isbreak = true;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										default:
 | 
				
			||||||
 | 
											throw new Exception($"表达式错误,它不是连续的 MemberAccess 类型:{exp}");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (param == null) throw new Exception($"表达式错误,它的顶级对象不是 ParameterExpression:{exp}");
 | 
				
			||||||
 | 
								return (param, members);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName");
 | 
							static MethodInfo GetEntityValueWithPropertyNameMethod = typeof(EntityUtilExtensions).GetMethod("GetEntityValueWithPropertyName");
 | 
				
			||||||
		static ConcurrentDictionary<Type, ConcurrentDictionary<string, MethodInfo>> _dicTypeMethod = new ConcurrentDictionary<Type, ConcurrentDictionary<string, MethodInfo>>();
 | 
							static ConcurrentDictionary<Type, ConcurrentDictionary<string, MethodInfo>> _dicTypeMethod = new ConcurrentDictionary<Type, ConcurrentDictionary<string, MethodInfo>>();
 | 
				
			||||||
		public ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavigate>>> navigateSelector, Action<ISelect<TNavigate>> then = null) where TNavigate : class {
 | 
							public ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavigate>>> navigateSelector, Action<ISelect<TNavigate>> then = null) where TNavigate : class {
 | 
				
			||||||
@@ -331,23 +355,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if (expBody.NodeType != ExpressionType.MemberAccess) throw throwNavigateSelector;
 | 
								if (expBody.NodeType != ExpressionType.MemberAccess) throw throwNavigateSelector;
 | 
				
			||||||
			var collMem = expBody as MemberExpression;
 | 
								var collMem = expBody as MemberExpression;
 | 
				
			||||||
			Expression tmpExp = collMem.Expression;
 | 
								var (membersParam, members) = GetExpressionStack(collMem.Expression);
 | 
				
			||||||
			var members = new Stack<MemberInfo>();
 | 
					 | 
				
			||||||
			var isbreak = false;
 | 
					 | 
				
			||||||
			while(isbreak == false) {
 | 
					 | 
				
			||||||
				switch (tmpExp.NodeType) {
 | 
					 | 
				
			||||||
					case ExpressionType.MemberAccess:
 | 
					 | 
				
			||||||
						var memExp = tmpExp as MemberExpression;
 | 
					 | 
				
			||||||
						tmpExp = memExp.Expression;
 | 
					 | 
				
			||||||
						members.Push(memExp.Member);
 | 
					 | 
				
			||||||
						continue;
 | 
					 | 
				
			||||||
					case ExpressionType.Parameter:
 | 
					 | 
				
			||||||
						isbreak = true;
 | 
					 | 
				
			||||||
						break;
 | 
					 | 
				
			||||||
					default:
 | 
					 | 
				
			||||||
						throw throwNavigateSelector;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			var tb = _commonUtils.GetTableByEntity(collMem.Expression.Type);
 | 
								var tb = _commonUtils.GetTableByEntity(collMem.Expression.Type);
 | 
				
			||||||
			if (tb == null) throw throwNavigateSelector;
 | 
								if (tb == null) throw throwNavigateSelector;
 | 
				
			||||||
			var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate));
 | 
								var tbNav = _commonUtils.GetTableByEntity(typeof(TNavigate));
 | 
				
			||||||
@@ -357,6 +365,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
				_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
 | 
									_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			TableRef tbref = null;
 | 
								TableRef tbref = null;
 | 
				
			||||||
 | 
								var tbrefOneToManyColumns = new List<List<MemberExpression>>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定
 | 
				
			||||||
			if (whereExp == null) {
 | 
								if (whereExp == null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				tbref = tb.GetTableRef(collMem.Member.Name, true);
 | 
									tbref = tb.GetTableRef(collMem.Member.Name, true);
 | 
				
			||||||
@@ -388,22 +397,48 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
								if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector;
 | 
													if (leftP1MemberExp == null || rightP1MemberExp == null) throw throwNavigateSelector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
								if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
 | 
													if (leftP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
 | 
				
			||||||
									var rightParExp = rightP1MemberExp;
 | 
														var (rightMembersParam, rightMembers) = GetExpressionStack(rightP1MemberExp.Expression);
 | 
				
			||||||
									while (rightParExp.Expression != tmpExp) {
 | 
														if (rightMembersParam != membersParam) throw throwNavigateSelector;
 | 
				
			||||||
										rightParExp = rightParExp.Expression as MemberExpression;
 | 
														var isCollMemEquals = rightMembers.Count == members.Count;
 | 
				
			||||||
										if (rightParExp == null) throw throwNavigateSelector;
 | 
														if (isCollMemEquals) {
 | 
				
			||||||
 | 
															for (var l = 0; l < members.Count; l++)
 | 
				
			||||||
 | 
																if (members[l].Member != rightMembers[l].Member) {
 | 
				
			||||||
 | 
																	isCollMemEquals = false;
 | 
				
			||||||
 | 
																	break;
 | 
				
			||||||
											}
 | 
																}
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
														if (isCollMemEquals) {
 | 
				
			||||||
										tbref.Columns.Add(tb.ColumnsByCs[rightP1MemberExp.Member.Name]);
 | 
															tbref.Columns.Add(tb.ColumnsByCs[rightP1MemberExp.Member.Name]);
 | 
				
			||||||
 | 
															tbrefOneToManyColumns.Add(null);
 | 
				
			||||||
 | 
														} else {
 | 
				
			||||||
 | 
															var tmpTb = _commonUtils.GetTableByEntity(rightP1MemberExp.Expression.Type);
 | 
				
			||||||
 | 
															if (tmpTb == null) throw throwNavigateSelector;
 | 
				
			||||||
 | 
															tbref.Columns.Add(tmpTb.ColumnsByCs[rightP1MemberExp.Member.Name]);
 | 
				
			||||||
 | 
															tbrefOneToManyColumns.Add(rightMembers);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
									tbref.RefColumns.Add(tbNav.ColumnsByCs[leftP1MemberExp.Member.Name]);
 | 
														tbref.RefColumns.Add(tbNav.ColumnsByCs[leftP1MemberExp.Member.Name]);
 | 
				
			||||||
									return;
 | 
														return;
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
								if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
 | 
													if (rightP1MemberExp.Expression == whereExpArgLamb.Parameters[0]) {
 | 
				
			||||||
									var leftParExp = leftP1MemberExp;
 | 
														var (leftMembersParam, leftMembers) = GetExpressionStack(leftP1MemberExp.Expression);
 | 
				
			||||||
									while (leftParExp.Expression != tmpExp) {
 | 
														if (leftMembersParam != membersParam) throw throwNavigateSelector;
 | 
				
			||||||
										leftParExp = leftParExp.Expression as MemberExpression;
 | 
														var isCollMemEquals = leftMembers.Count == members.Count;
 | 
				
			||||||
										if (leftParExp == null) throw throwNavigateSelector;
 | 
														if (isCollMemEquals) {
 | 
				
			||||||
 | 
															for (var l = 0; l < members.Count; l++)
 | 
				
			||||||
 | 
																if (members[l].Member != leftMembers[l].Member) {
 | 
				
			||||||
 | 
																	isCollMemEquals = false;
 | 
				
			||||||
 | 
																	break;
 | 
				
			||||||
											}
 | 
																}
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
 | 
														if (isCollMemEquals) {
 | 
				
			||||||
										tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]);
 | 
															tbref.Columns.Add(tb.ColumnsByCs[leftP1MemberExp.Member.Name]);
 | 
				
			||||||
 | 
															tbrefOneToManyColumns.Add(null);
 | 
				
			||||||
 | 
														} else {
 | 
				
			||||||
 | 
															var tmpTb = _commonUtils.GetTableByEntity(leftP1MemberExp.Expression.Type);
 | 
				
			||||||
 | 
															if (tmpTb == null) throw throwNavigateSelector;
 | 
				
			||||||
 | 
															tbref.Columns.Add(tmpTb.ColumnsByCs[leftP1MemberExp.Member.Name]);
 | 
				
			||||||
 | 
															tbrefOneToManyColumns.Add(leftMembers);
 | 
				
			||||||
 | 
														}
 | 
				
			||||||
									tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]);
 | 
														tbref.RefColumns.Add(tbNav.ColumnsByCs[rightP1MemberExp.Member.Name]);
 | 
				
			||||||
									return;
 | 
														return;
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
@@ -422,12 +457,12 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
				var list = listObj as List<T1>;
 | 
									var list = listObj as List<T1>;
 | 
				
			||||||
				if (list == null) return;
 | 
									if (list == null) return;
 | 
				
			||||||
				if (list.Any() == false) return;
 | 
									if (list.Any() == false) return;
 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (tbref.Columns.Any() == false) return;
 | 
									if (tbref.Columns.Any() == false) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var t1parm = Expression.Parameter(typeof(T1));
 | 
									var t1parm = Expression.Parameter(typeof(T1));
 | 
				
			||||||
				Expression membersExp = t1parm;
 | 
									Expression membersExp = t1parm;
 | 
				
			||||||
				while (members.Any()) membersExp = Expression.MakeMemberAccess(membersExp, members.Pop());
 | 
									foreach(var mem in members) membersExp = Expression.MakeMemberAccess(membersExp, mem.Member);
 | 
				
			||||||
 | 
									members.Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var listValueExp = Expression.Parameter(typeof(List<TNavigate>), "listValue");
 | 
									var listValueExp = Expression.Parameter(typeof(List<TNavigate>), "listValue");
 | 
				
			||||||
				var setListValue = Expression.Lambda<Action<T1, List<TNavigate>>>(
 | 
									var setListValue = Expression.Lambda<Action<T1, List<TNavigate>>>(
 | 
				
			||||||
@@ -438,12 +473,33 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				var returnTarget = Expression.Label(typeof(object));
 | 
									var returnTarget = Expression.Label(typeof(object));
 | 
				
			||||||
				var propertyNameExp = Expression.Parameter(typeof(string), "propertyName");
 | 
									var propertyNameExp = Expression.Parameter(typeof(string), "propertyName");
 | 
				
			||||||
				var getListValue = Expression.Lambda<Func<T1, string, object>>(
 | 
									var getListValue1 = Expression.Lambda<Func<T1, string, object>>(
 | 
				
			||||||
					Expression.Block(
 | 
										Expression.Block(
 | 
				
			||||||
						Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)),
 | 
											Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(membersExp.Type), membersExp, propertyNameExp)),
 | 
				
			||||||
						Expression.Label(returnTarget, Expression.Default(typeof(object)))
 | 
											Expression.Label(returnTarget, Expression.Default(typeof(object)))
 | 
				
			||||||
					), t1parm, propertyNameExp).Compile();
 | 
										), t1parm, propertyNameExp).Compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									var getListValue2 = new List<Func<T1, string, object>>();
 | 
				
			||||||
 | 
									for (var j = 0; j < tbrefOneToManyColumns.Count; j++) {
 | 
				
			||||||
 | 
										if (tbrefOneToManyColumns[j] == null) {
 | 
				
			||||||
 | 
											getListValue2.Add(null);
 | 
				
			||||||
 | 
											continue;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										Expression tbrefOneToManyColumnsMembers = t1parm;
 | 
				
			||||||
 | 
										foreach (var mem in tbrefOneToManyColumns[j]) tbrefOneToManyColumnsMembers = Expression.MakeMemberAccess(tbrefOneToManyColumnsMembers, mem.Member);
 | 
				
			||||||
 | 
										tbrefOneToManyColumns[j].Clear();
 | 
				
			||||||
 | 
										getListValue2.Add(Expression.Lambda<Func<T1, string, object>>(
 | 
				
			||||||
 | 
											Expression.Block(
 | 
				
			||||||
 | 
												Expression.Return(returnTarget, Expression.Call(null, GetEntityValueWithPropertyNameMethod, Expression.Constant(_orm), Expression.Constant(tbrefOneToManyColumnsMembers.Type), tbrefOneToManyColumnsMembers, propertyNameExp)),
 | 
				
			||||||
 | 
												Expression.Label(returnTarget, Expression.Default(typeof(object)))
 | 
				
			||||||
 | 
											), t1parm, propertyNameExp).Compile());
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									tbrefOneToManyColumns.Clear();
 | 
				
			||||||
 | 
									Func<T1, string, int, object> getListValue = (item, propName, colIndex) => {
 | 
				
			||||||
 | 
										if (getListValue2.Any() && getListValue2[colIndex] != null) return getListValue2[colIndex](item, propName);
 | 
				
			||||||
 | 
										return getListValue1(item, propName);
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				foreach (var item in list) {
 | 
									foreach (var item in list) {
 | 
				
			||||||
					setListValue(item, null);
 | 
										setListValue(item, null);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -457,7 +513,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
							var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
 | 
												var tbref2 = _commonUtils.GetTableByEntity(tbref.RefEntityType);
 | 
				
			||||||
							if (tbref.Columns.Count == 1) {
 | 
												if (tbref.Columns.Count == 1) {
 | 
				
			||||||
								var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, 
 | 
													var arrExp = Expression.NewArrayInit(tbref.Columns[0].CsType, 
 | 
				
			||||||
									list.Select(a => getListValue(a, tbref.Columns[0].CsName)).Distinct()
 | 
														list.Select(a => getListValue(a, tbref.Columns[0].CsName, 0)).Distinct()
 | 
				
			||||||
										.Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).ToArray());
 | 
															.Select(a => Expression.Constant(Convert.ChangeType(a, tbref.Columns[0].CsType))).ToArray());
 | 
				
			||||||
								var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
 | 
													var otmExpParm1 = Expression.Parameter(typeof(TNavigate), "a");
 | 
				
			||||||
								var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
 | 
													var containsMethod = _dicTypeMethod.GetOrAdd(tbref.Columns[0].CsType, et => new ConcurrentDictionary<string, MethodInfo>()).GetOrAdd("Contains", mn =>
 | 
				
			||||||
@@ -474,7 +530,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
									sbWhereOne.Append("(");
 | 
														sbWhereOne.Append("(");
 | 
				
			||||||
									for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
														for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
				
			||||||
										if (z > 0) sbWhereOne.Append(" AND ");
 | 
															if (z > 0) sbWhereOne.Append(" AND ");
 | 
				
			||||||
										sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName)));
 | 
															sbWhereOne.Append(_commonUtils.FormatSql($"{subSelectT1Alias}.{_commonUtils.QuoteSqlName(tbref.RefColumns[z].Attribute.Name)}={{0}}", getListValue(list[y], tbref.Columns[z].CsName, z)));
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
									sbWhereOne.Append(")");
 | 
														sbWhereOne.Append(")");
 | 
				
			||||||
									var whereOne = sbWhereOne.ToString();
 | 
														var whereOne = sbWhereOne.ToString();
 | 
				
			||||||
@@ -512,14 +568,14 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
							Dictionary<string, Tuple<T1, List<TNavigate>>> dicList = new Dictionary<string, Tuple<T1, List<TNavigate>>>();
 | 
												Dictionary<string, Tuple<T1, List<TNavigate>>> dicList = new Dictionary<string, Tuple<T1, List<TNavigate>>>();
 | 
				
			||||||
							foreach (var item in list) {
 | 
												foreach (var item in list) {
 | 
				
			||||||
								if (tbref.Columns.Count == 1) {
 | 
													if (tbref.Columns.Count == 1) {
 | 
				
			||||||
									dicList.Add(getListValue(item, tbref.Columns[0].CsName).ToString(), Tuple.Create(item, new List<TNavigate>()));
 | 
														dicList.Add(getListValue(item, tbref.Columns[0].CsName, 0).ToString(), Tuple.Create(item, new List<TNavigate>()));
 | 
				
			||||||
								} else {
 | 
													} else {
 | 
				
			||||||
									var sb = new StringBuilder();
 | 
														var sb = new StringBuilder();
 | 
				
			||||||
									for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
														for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
				
			||||||
										if (z > 0) sb.Append("*$*");
 | 
															if (z > 0) sb.Append("*$*");
 | 
				
			||||||
										sb.Append(getListValue(item, tbref.Columns[z].CsName));
 | 
															sb.Append(getListValue(item, tbref.Columns[z].CsName, z));
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
									dicList.Add(sb.Remove(0, 3).ToString(), Tuple.Create(item, new List<TNavigate>()));
 | 
														dicList.Add(sb.ToString(), Tuple.Create(item, new List<TNavigate>()));
 | 
				
			||||||
									sb.Clear();
 | 
														sb.Clear();
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
@@ -570,7 +626,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
							subSelect.InnerJoin(sbJoin.ToString());
 | 
												subSelect.InnerJoin(sbJoin.ToString());
 | 
				
			||||||
							sbJoin.Clear();
 | 
												sbJoin.Clear();
 | 
				
			||||||
							if (tbref.Columns.Count == 1) {
 | 
												if (tbref.Columns.Count == 1) {
 | 
				
			||||||
								subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue(a, tbref.Columns[0].CsName)).Distinct()));
 | 
													subSelect.Where(_commonUtils.FormatSql($"midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[0].Attribute.Name)} in {{0}}", list.Select(a => getListValue1(a, tbref.Columns[0].CsName)).Distinct()));
 | 
				
			||||||
							} else {
 | 
												} else {
 | 
				
			||||||
								Dictionary<string, bool> sbDic = new Dictionary<string, bool>();
 | 
													Dictionary<string, bool> sbDic = new Dictionary<string, bool>();
 | 
				
			||||||
								for (var y = 0; y < list.Count; y++) {
 | 
													for (var y = 0; y < list.Count; y++) {
 | 
				
			||||||
@@ -578,7 +634,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
									sbWhereOne.Append("(");
 | 
														sbWhereOne.Append("(");
 | 
				
			||||||
									for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
														for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
				
			||||||
										if (z > 0) sbWhereOne.Append(" AND ");
 | 
															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(_commonUtils.FormatSql($" midtb.{_commonUtils.QuoteSqlName(tbref.MiddleColumns[z].Attribute.Name)}={{0}}", getListValue1(list[y], tbref.Columns[z].CsName)));
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
									sbWhereOne.Append(")");
 | 
														sbWhereOne.Append(")");
 | 
				
			||||||
									var whereOne = sbWhereOne.ToString();
 | 
														var whereOne = sbWhereOne.ToString();
 | 
				
			||||||
@@ -588,7 +644,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
								var sbWhere = new StringBuilder();
 | 
													var sbWhere = new StringBuilder();
 | 
				
			||||||
								foreach (var sbd in sbDic)
 | 
													foreach (var sbd in sbDic)
 | 
				
			||||||
									sbWhere.Append(" OR ").Append(sbd.Key);
 | 
														sbWhere.Append(" OR ").Append(sbd.Key);
 | 
				
			||||||
								subSelect.Where(sbWhere.Remove(0, 3).ToString());
 | 
													subSelect.Where(sbWhere.Remove(0, 4).ToString());
 | 
				
			||||||
								sbWhere.Clear();
 | 
													sbWhere.Clear();
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							then?.Invoke(subSelect);
 | 
												then?.Invoke(subSelect);
 | 
				
			||||||
@@ -629,7 +685,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
							Dictionary<string, List<Tuple<T1, List<TNavigate>>>> dicList = new Dictionary<string, List<Tuple<T1, List<TNavigate>>>>();
 | 
												Dictionary<string, List<Tuple<T1, List<TNavigate>>>> dicList = new Dictionary<string, List<Tuple<T1, List<TNavigate>>>>();
 | 
				
			||||||
							foreach (var item in list) {
 | 
												foreach (var item in list) {
 | 
				
			||||||
								if (tbref.Columns.Count == 1) {
 | 
													if (tbref.Columns.Count == 1) {
 | 
				
			||||||
									var dicListKey = getListValue(item, tbref.Columns[0].CsName).ToString();
 | 
														var dicListKey = getListValue1(item, tbref.Columns[0].CsName).ToString();
 | 
				
			||||||
									var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
														var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
				
			||||||
									if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
														if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
				
			||||||
										dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
															dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
				
			||||||
@@ -638,9 +694,9 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
									var sb = new StringBuilder();
 | 
														var sb = new StringBuilder();
 | 
				
			||||||
									for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
														for (var z = 0; z < tbref.Columns.Count; z++) {
 | 
				
			||||||
										if (z > 0) sb.Append("*$*");
 | 
															if (z > 0) sb.Append("*$*");
 | 
				
			||||||
										sb.Append(getListValue(item, tbref.Columns[z].CsName));
 | 
															sb.Append(getListValue1(item, tbref.Columns[z].CsName));
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
									var dicListKey = sb.Remove(0, 3).ToString();
 | 
														var dicListKey = sb.ToString();
 | 
				
			||||||
									var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
														var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
				
			||||||
									if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
														if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
				
			||||||
										dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
															dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user