mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 补充 异步方法 ToListAsync(a => {}) 对 IncludeMany 的支持;
This commit is contained in:
		@@ -195,7 +195,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            _tables[0].Parameter = select.Parameters[0];
 | 
			
		||||
            if (_includeToList?.Any() != true) return this.InternalToList<TReturn>(select.Body);
 | 
			
		||||
 | 
			
		||||
            var findIncludeMany = new List<string>();
 | 
			
		||||
            var findIncludeMany = new List<string>(); //支持指定已经使用 IncudeMany 的导航属性
 | 
			
		||||
            var map = new ReadAnonymousTypeInfo();
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
@@ -1167,11 +1167,72 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            _tables[0].Parameter = column.Parameters[0];
 | 
			
		||||
            return this.InternalSumAsync(column?.Body);
 | 
			
		||||
        }
 | 
			
		||||
        public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<T1, TReturn>> select)
 | 
			
		||||
        async public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<T1, TReturn>> select)
 | 
			
		||||
        {
 | 
			
		||||
            if (select == null) return this.InternalToListAsync<TReturn>(select?.Body);
 | 
			
		||||
            if (select == null) return await this.InternalToListAsync<TReturn>(select?.Body);
 | 
			
		||||
            _tables[0].Parameter = select.Parameters[0];
 | 
			
		||||
            return this.InternalToListAsync<TReturn>(select?.Body);
 | 
			
		||||
            if (_includeToList?.Any() != true) return await this.InternalToListAsync<TReturn>(select.Body);
 | 
			
		||||
 | 
			
		||||
            var findIncludeMany = new List<string>(); //支持指定已经使用 IncudeMany 的导航属性
 | 
			
		||||
            var map = new ReadAnonymousTypeInfo();
 | 
			
		||||
            var field = new StringBuilder();
 | 
			
		||||
            var index = 0;
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select.Body, this, null, _whereCascadeExpression, findIncludeMany, true);
 | 
			
		||||
            var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
			
		||||
            if (findIncludeMany.Any() == false) return await this.ToListMapReaderPrivateAsync<TReturn>(af, null);
 | 
			
		||||
 | 
			
		||||
            var parmExp = Expression.Parameter(_tables[0].Table.Type, _tables[0].Alias);
 | 
			
		||||
            var incNewInit = new IncludeManyNewInit(_tables[0].Table, parmExp);
 | 
			
		||||
            foreach (var inc in _includeInfo)
 | 
			
		||||
            {
 | 
			
		||||
                var curIncNewInit = incNewInit;
 | 
			
		||||
                Expression curParmExp = parmExp;
 | 
			
		||||
                for (var a = 0; a < inc.Value.Length - 1; a++)
 | 
			
		||||
                {
 | 
			
		||||
                    curParmExp = Expression.MakeMemberAccess(parmExp, inc.Value[a].Member);
 | 
			
		||||
                    if (curIncNewInit.Childs.ContainsKey(inc.Value[a].Member.Name) == false)
 | 
			
		||||
                        curIncNewInit.Childs.Add(inc.Value[a].Member.Name, curIncNewInit = new IncludeManyNewInit(_orm.CodeFirst.GetTableByEntity(inc.Value[a].Type), curParmExp));
 | 
			
		||||
                    else
 | 
			
		||||
                        curIncNewInit = curIncNewInit.Childs[inc.Value[a].Member.Name];
 | 
			
		||||
                }
 | 
			
		||||
                curIncNewInit.IsOutputPrimary = true;
 | 
			
		||||
            }
 | 
			
		||||
            MemberInitExpression GetIncludeManyNewInitExpression(IncludeManyNewInit imni)
 | 
			
		||||
            {
 | 
			
		||||
                var bindings = new List<MemberBinding>();
 | 
			
		||||
                if (imni.IsOutputPrimary) bindings.AddRange(imni.Table.Primarys.Select(a => Expression.Bind(imni.Table.Properties[a.CsName], Expression.MakeMemberAccess(imni.CurrentExpression, imni.Table.Properties[a.CsName]))));
 | 
			
		||||
                if (imni.Childs.Any()) bindings.AddRange(imni.Childs.Select(a => Expression.Bind(imni.Table.Properties[a.Key], GetIncludeManyNewInitExpression(a.Value))));
 | 
			
		||||
                return Expression.MemberInit(imni.Table.Type.InternalNewExpression(), bindings);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var otherNewInit = GetIncludeManyNewInitExpression(incNewInit); //获取 IncludeMany 包含的最简化字段
 | 
			
		||||
            if (otherNewInit.Bindings.Any() == false) return await this.ToListMapReaderPrivateAsync<TReturn>(af, null);
 | 
			
		||||
 | 
			
		||||
            var otherMap = new ReadAnonymousTypeInfo();
 | 
			
		||||
            field.Clear();
 | 
			
		||||
            _commonExpression.ReadAnonymousField(_tables, field, otherMap, ref index, otherNewInit, this, null, _whereCascadeExpression, null, true);
 | 
			
		||||
            var otherRet = new List<object>();
 | 
			
		||||
            var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet);
 | 
			
		||||
 | 
			
		||||
            af.fillIncludeMany = new List<NativeTuple<string, IList, int>>();
 | 
			
		||||
            var ret = await this.ToListMapReaderPrivateAsync<TReturn>(af, new[] { otherAf });
 | 
			
		||||
            await this.SetListAsync(otherRet.Select(a => (T1)a).ToList()); //级联加载
 | 
			
		||||
 | 
			
		||||
            foreach (var fim in af.fillIncludeMany)
 | 
			
		||||
            {
 | 
			
		||||
                var splitKeys = fim.Item1.Split('.');
 | 
			
		||||
                var otherRetItem = otherRet[fim.Item3];
 | 
			
		||||
                var otherRetItemType = _tables[0].Table.Type;
 | 
			
		||||
                foreach (var splitKey in splitKeys)
 | 
			
		||||
                {
 | 
			
		||||
                    otherRetItem = _orm.GetEntityValueWithPropertyName(otherRetItemType, otherRetItem, splitKey);
 | 
			
		||||
                    otherRetItemType = _orm.CodeFirst.GetTableByEntity(otherRetItemType).Properties[splitKey].PropertyType;
 | 
			
		||||
                }
 | 
			
		||||
                if (otherRetItem == null) continue;
 | 
			
		||||
                var otherList = otherRetItem as IEnumerable;
 | 
			
		||||
                foreach (var otherListItem in otherList) fim.Item2.Add(otherListItem);
 | 
			
		||||
            }
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
        public Task<List<TDto>> ToListAsync<TDto>() => ToListAsync(GetToListDtoSelector<TDto>());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user