mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 增加 ISelect.ToTreeList 扩展方法查询数据,加工为树型 List;(注意:实体需要配置父子导航属性)
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					<Project Sdk="Microsoft.NET.Sdk">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
					  <PropertyGroup>
 | 
				
			||||||
    <RootNamespace>FreeSql.Tests.VB</RootNamespace>
 | 
					    <RootNamespace>FreeSql.Tests.VB</RootNamespace>
 | 
				
			||||||
@@ -15,6 +15,7 @@
 | 
				
			|||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <ProjectReference Include="..\Extensions\FreeSql.Extensions.BaseEntity\FreeSql.Extensions.BaseEntity.csproj" />
 | 
				
			||||||
    <ProjectReference Include="..\Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj" />
 | 
					    <ProjectReference Include="..\Extensions\FreeSql.Extensions.LazyLoading\FreeSql.Extensions.LazyLoading.csproj" />
 | 
				
			||||||
    <ProjectReference Include="..\FreeSql.DbContext\FreeSql.DbContext.csproj" />
 | 
					    <ProjectReference Include="..\FreeSql.DbContext\FreeSql.DbContext.csproj" />
 | 
				
			||||||
    <ProjectReference Include="..\Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj" />
 | 
					    <ProjectReference Include="..\Providers\FreeSql.Provider.SqlServer\FreeSql.Provider.SqlServer.csproj" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
Imports System
 | 
					Imports System
 | 
				
			||||||
 | 
					Imports FreeSql.DataAnnotations
 | 
				
			||||||
Imports Xunit
 | 
					Imports Xunit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Namespace FreeSql.Tests.VB
 | 
					Namespace FreeSql.Tests.VB
 | 
				
			||||||
@@ -38,6 +39,17 @@ Namespace FreeSql.Tests.VB
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            Dim List9 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList()
 | 
					            Dim List9 = g.sqlserver.Select(Of Testvb).IncludeMany(Function(a) a.Testvb2s).ToList()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            BaseEntity.Initialization(g.sqlserver)
 | 
				
			||||||
 | 
					            Dim cowR As CowRecord = New CowRecord
 | 
				
			||||||
 | 
					            cowR.Id = 1
 | 
				
			||||||
 | 
					            cowR.Lact = 1
 | 
				
			||||||
 | 
					            cowR.VetCount = 1
 | 
				
			||||||
 | 
					            cowR.Save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cowR.VetCount += 1
 | 
				
			||||||
 | 
					            cowR.Update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        End Sub
 | 
					        End Sub
 | 
				
			||||||
    End Class
 | 
					    End Class
 | 
				
			||||||
@@ -58,3 +70,52 @@ Class Testvb2
 | 
				
			|||||||
    Property Testvb As Testvb
 | 
					    Property Testvb As Testvb
 | 
				
			||||||
    Property Context As String
 | 
					    Property Context As String
 | 
				
			||||||
End Class
 | 
					End Class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Index("uk_Primary", "Id,Lact", True)>
 | 
				
			||||||
 | 
					Public Class CowRecord
 | 
				
			||||||
 | 
					    Inherits BaseEntity(Of CowRecord)
 | 
				
			||||||
 | 
					    Private _Id As Integer
 | 
				
			||||||
 | 
					    Private _Lact As Integer
 | 
				
			||||||
 | 
					    Private _Pen As Integer
 | 
				
			||||||
 | 
					    Private _BDAT As Date?
 | 
				
			||||||
 | 
					    Private _FDAT As Date?
 | 
				
			||||||
 | 
					    Private _DDAT As Date?
 | 
				
			||||||
 | 
					    Private _EDAT As Date?
 | 
				
			||||||
 | 
					    Private _ARDAT As Date?
 | 
				
			||||||
 | 
					    Private _MKDAT As Date?
 | 
				
			||||||
 | 
					    Private _BFDAT As Date?
 | 
				
			||||||
 | 
					    Private _USDAT As Date?
 | 
				
			||||||
 | 
					    Private _RC As Integer
 | 
				
			||||||
 | 
					    Private _DMLK1 As Integer
 | 
				
			||||||
 | 
					    Private _VetCount As Integer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <Column(IsPrimary:=True)>
 | 
				
			||||||
 | 
					    Public Property Id As Integer
 | 
				
			||||||
 | 
					        Get
 | 
				
			||||||
 | 
					            Return _Id
 | 
				
			||||||
 | 
					        End Get
 | 
				
			||||||
 | 
					        Set(value As Integer)
 | 
				
			||||||
 | 
					            _Id = value
 | 
				
			||||||
 | 
					        End Set
 | 
				
			||||||
 | 
					    End Property
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <Column(IsPrimary:=True)>
 | 
				
			||||||
 | 
					    Public Property Lact As Integer
 | 
				
			||||||
 | 
					        Get
 | 
				
			||||||
 | 
					            Return _Lact
 | 
				
			||||||
 | 
					        End Get
 | 
				
			||||||
 | 
					        Set(value As Integer)
 | 
				
			||||||
 | 
					            _Lact = value
 | 
				
			||||||
 | 
					        End Set
 | 
				
			||||||
 | 
					    End Property
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Public Property VetCount As Integer
 | 
				
			||||||
 | 
					        Get
 | 
				
			||||||
 | 
					            Return _VetCount
 | 
				
			||||||
 | 
					        End Get
 | 
				
			||||||
 | 
					        Set(value As Integer)
 | 
				
			||||||
 | 
					            _VetCount = value
 | 
				
			||||||
 | 
					        End Set
 | 
				
			||||||
 | 
					    End Property
 | 
				
			||||||
 | 
					End Class
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
using Xunit;
 | 
					using Xunit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Tests
 | 
					namespace FreeSql.Tests
 | 
				
			||||||
@@ -318,6 +319,7 @@ namespace FreeSql.Tests
 | 
				
			|||||||
            cts[1].Goodss.Clear();
 | 
					            cts[1].Goodss.Clear();
 | 
				
			||||||
            cts[1].Goodss.Add(new Goods { Name = "<22><>Ʒ55" });
 | 
					            cts[1].Goodss.Add(new Goods { Name = "<22><>Ʒ55" });
 | 
				
			||||||
            repo.Update(cts);
 | 
					            repo.Update(cts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Table(Name = "EAUNL_OTM_CT")]
 | 
					        [Table(Name = "EAUNL_OTM_CT")]
 | 
				
			||||||
        class Cagetory
 | 
					        class Cagetory
 | 
				
			||||||
@@ -390,6 +392,7 @@ namespace FreeSql.Tests
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void EnableAddOrUpdateNavigateList_OneToMany_Parent()
 | 
					        public void EnableAddOrUpdateNavigateList_OneToMany_Parent()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            g.sqlite.Delete<CagetoryParent>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
            var repo = g.sqlite.GetRepository<CagetoryParent>();
 | 
					            var repo = g.sqlite.GetRepository<CagetoryParent>();
 | 
				
			||||||
            var cts = new[] {
 | 
					            var cts = new[] {
 | 
				
			||||||
                new CagetoryParent
 | 
					                new CagetoryParent
 | 
				
			||||||
@@ -412,9 +415,12 @@ namespace FreeSql.Tests
 | 
				
			|||||||
                    })
 | 
					                    })
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            repo.DbContextOptions.EnableAddOrUpdateNavigateList = false; //<2F>رռ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>湦<EFBFBD><EFBFBD>
 | 
					            repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; //<2F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>湦<EFBFBD><EFBFBD>
 | 
				
			||||||
            repo.Insert(cts);
 | 
					            repo.Insert(cts);
 | 
				
			||||||
            repo.SaveMany(cts[0], "Childs"); //ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Childs һ<>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
 | 
					
 | 
				
			||||||
 | 
					            var treelist1 = repo.Select.ToTreeList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //repo.SaveMany(cts[0], "Childs"); //ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Childs һ<>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
 | 
				
			||||||
            cts[0].Name = "<22><><EFBFBD><EFBFBD>11";
 | 
					            cts[0].Name = "<22><><EFBFBD><EFBFBD>11";
 | 
				
			||||||
            cts[0].Childs.Clear();
 | 
					            cts[0].Childs.Clear();
 | 
				
			||||||
            cts[1].Name = "<22><><EFBFBD><EFBFBD>22";
 | 
					            cts[1].Name = "<22><><EFBFBD><EFBFBD>22";
 | 
				
			||||||
@@ -427,6 +433,7 @@ namespace FreeSql.Tests
 | 
				
			|||||||
            cts[1].Childs.Clear();
 | 
					            cts[1].Childs.Clear();
 | 
				
			||||||
            cts[1].Childs.Add(new CagetoryParent { Name = "<22><><EFBFBD><EFBFBD>2_22" });
 | 
					            cts[1].Childs.Add(new CagetoryParent { Name = "<22><><EFBFBD><EFBFBD>2_22" });
 | 
				
			||||||
            repo.Update(cts);
 | 
					            repo.Update(cts);
 | 
				
			||||||
 | 
					            var treelist2 = repo.Select.ToTreeList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Table(Name = "EAUNL_OTMP_CT")]
 | 
					        [Table(Name = "EAUNL_OTMP_CT")]
 | 
				
			||||||
        class CagetoryParent
 | 
					        class CagetoryParent
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
using FreeSql;
 | 
					using FreeSql;
 | 
				
			||||||
using FreeSql.DataAnnotations;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
 | 
					using FreeSql.Internal.CommonProvider;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
@@ -246,6 +247,61 @@ public static partial class FreeSqlGlobalExtensions
 | 
				
			|||||||
        await select.SetListAsync(list);
 | 
					        await select.SetListAsync(list);
 | 
				
			||||||
        return list;
 | 
					        return list;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #region ToTreeList() 父子分类
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// 查询数据,加工为树型 List 返回<para></para>
 | 
				
			||||||
 | 
					    /// 注意:实体需要配置父子导航属性
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <typeparam name="T1"></typeparam>
 | 
				
			||||||
 | 
					    /// <param name="that"></param>
 | 
				
			||||||
 | 
					    /// <returns></returns>
 | 
				
			||||||
 | 
					    public static List<T1> ToTreeList<T1>(this ISelect<T1> that) where T1 : class
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var select = that as Select1Provider<T1>;
 | 
				
			||||||
 | 
					        var tb = select._tables[0].Table;
 | 
				
			||||||
 | 
					        var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false))
 | 
				
			||||||
 | 
					            .Where(a => a != null && 
 | 
				
			||||||
 | 
					                a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany &&
 | 
				
			||||||
 | 
					                a.RefEntityType == tb.Type).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (navs.Length != 1) return select.ToList();
 | 
				
			||||||
 | 
					        var list = select.ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        select._trackToList = null;
 | 
				
			||||||
 | 
					        select._includeToList.Clear();
 | 
				
			||||||
 | 
					        var navigateSelectorParamExp = select._tables[0].Parameter ?? Expression.Parameter(typeof(T1), select._tables[0].Alias);
 | 
				
			||||||
 | 
					        var navigateSelector = Expression.Lambda<Func<T1, IEnumerable<T1>>>(Expression.MakeMemberAccess(navigateSelectorParamExp, navs[0].Property), navigateSelectorParamExp);
 | 
				
			||||||
 | 
					        select.IncludeMany(navigateSelector);
 | 
				
			||||||
 | 
					        select._includeManySubListOneToManyTempValue1 = list;
 | 
				
			||||||
 | 
					        select.SetList(list);
 | 
				
			||||||
 | 
					        return list.Except(list.SelectMany(a => FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityValueWithPropertyName(select._orm, tb.Type, a, navs[0].Property.Name) as IEnumerable<T1>)).ToList();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#if net40
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    async public static System.Threading.Tasks.Task<List<T1>> ToTreeListAsync<T1>(this ISelect<T1> that) where T1 : class
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var select = that as Select1Provider<T1>;
 | 
				
			||||||
 | 
					        var tb = select._tables[0].Table;
 | 
				
			||||||
 | 
					        var navs = tb.Properties.Select(a => tb.GetTableRef(a.Key, false))
 | 
				
			||||||
 | 
					            .Where(a => a != null &&
 | 
				
			||||||
 | 
					                a.RefType == FreeSql.Internal.Model.TableRefType.OneToMany &&
 | 
				
			||||||
 | 
					                a.RefEntityType == tb.Type).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (navs.Length != 1) return await select.ToListAsync();
 | 
				
			||||||
 | 
					        var list = await select.ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        select._trackToList = null;
 | 
				
			||||||
 | 
					        select._includeToList.Clear();
 | 
				
			||||||
 | 
					        var navigateSelectorParamExp = select._tables[0].Parameter ?? Expression.Parameter(typeof(T1), select._tables[0].Alias);
 | 
				
			||||||
 | 
					        var navigateSelector = Expression.Lambda<Func<T1, IEnumerable<T1>>>(Expression.MakeMemberAccess(navigateSelectorParamExp, navs[0].Property), navigateSelectorParamExp);
 | 
				
			||||||
 | 
					        select.IncludeMany(navigateSelector);
 | 
				
			||||||
 | 
					        select._includeManySubListOneToManyTempValue1 = list;
 | 
				
			||||||
 | 
					        select.SetList(list);
 | 
				
			||||||
 | 
					        return list.Except(list.SelectMany(a => FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityValueWithPropertyName(select._orm, tb.Type, a, navs[0].Property.Name) as IEnumerable<T1>)).ToList();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    #endregion
 | 
					    #endregion
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -3080,6 +3080,15 @@
 | 
				
			|||||||
            <param name="then">即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?)</param>
 | 
					            <param name="then">即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?)</param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSqlGlobalExtensions.ToTreeList``1(FreeSql.ISelect{``0})">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            查询数据,加工为树型 List 返回<para></para>
 | 
				
			||||||
 | 
					            注意:实体需要配置父子导航属性
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <typeparam name="T1"></typeparam>
 | 
				
			||||||
 | 
					            <param name="that"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
 | 
					        <member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``1(System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            使用 and 拼接两个 lambda 表达式
 | 
					            使用 and 拼接两个 lambda 表达式
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,18 +23,18 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
        protected string _select = "SELECT ", _orderby, _groupby, _having;
 | 
					        protected string _select = "SELECT ", _orderby, _groupby, _having;
 | 
				
			||||||
        protected StringBuilder _where = new StringBuilder();
 | 
					        protected StringBuilder _where = new StringBuilder();
 | 
				
			||||||
        protected List<DbParameter> _params = new List<DbParameter>();
 | 
					        protected List<DbParameter> _params = new List<DbParameter>();
 | 
				
			||||||
        protected List<SelectTableInfo> _tables = new List<SelectTableInfo>();
 | 
					        internal protected List<SelectTableInfo> _tables = new List<SelectTableInfo>();
 | 
				
			||||||
        protected List<Func<Type, string, string>> _tableRules = new List<Func<Type, string, string>>();
 | 
					        protected List<Func<Type, string, string>> _tableRules = new List<Func<Type, string, string>>();
 | 
				
			||||||
        protected Func<Type, string, string> _aliasRule;
 | 
					        protected Func<Type, string, string> _aliasRule;
 | 
				
			||||||
        protected string _tosqlAppendContent;
 | 
					        protected string _tosqlAppendContent;
 | 
				
			||||||
        protected StringBuilder _join = new StringBuilder();
 | 
					        protected StringBuilder _join = new StringBuilder();
 | 
				
			||||||
        protected IFreeSql _orm;
 | 
					        internal protected IFreeSql _orm;
 | 
				
			||||||
        protected CommonUtils _commonUtils;
 | 
					        protected CommonUtils _commonUtils;
 | 
				
			||||||
        protected CommonExpression _commonExpression;
 | 
					        protected CommonExpression _commonExpression;
 | 
				
			||||||
        protected DbTransaction _transaction;
 | 
					        protected DbTransaction _transaction;
 | 
				
			||||||
        protected DbConnection _connection;
 | 
					        protected DbConnection _connection;
 | 
				
			||||||
        protected Action<object> _trackToList;
 | 
					        internal protected Action<object> _trackToList;
 | 
				
			||||||
        protected List<Action<object>> _includeToList = new List<Action<object>>();
 | 
					        internal protected List<Action<object>> _includeToList = new List<Action<object>>();
 | 
				
			||||||
#if net40
 | 
					#if net40
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        protected List<Func<object, Task>> _includeToListAsync = new List<Func<object, Task>>();
 | 
					        protected List<Func<object, Task>> _includeToListAsync = new List<Func<object, Task>>();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -659,6 +659,93 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                foreach (var item in list)
 | 
					                foreach (var item in list)
 | 
				
			||||||
                    setListValue(item, null);
 | 
					                    setListValue(item, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Action<List<TNavigate>, TableInfo> fillOneToManyData = (subList, tbref2) =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (subList.Any() == false)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        foreach (var item in list)
 | 
				
			||||||
 | 
					                            setListValue(item, new List<TNavigate>());
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Dictionary<string, List<Tuple<T1, List<TNavigate>>>> dicList = new Dictionary<string, List<Tuple<T1, List<TNavigate>>>>();
 | 
				
			||||||
 | 
					                    foreach (var item in list)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (tbref.Columns.Count == 1)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString();
 | 
				
			||||||
 | 
					                            if (dicListKey == null) continue;
 | 
				
			||||||
 | 
					                            var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
				
			||||||
 | 
					                            if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
				
			||||||
 | 
					                                dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
				
			||||||
 | 
					                            items.Add(dicListVal);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var sb = new StringBuilder();
 | 
				
			||||||
 | 
					                            for (var z = 0; z < tbref.Columns.Count; z++)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if (z > 0) sb.Append("*$*");
 | 
				
			||||||
 | 
					                                sb.Append(getListValue(item, tbref.Columns[z].CsName, z));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            var dicListKey = sb.ToString();
 | 
				
			||||||
 | 
					                            var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
				
			||||||
 | 
					                            if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
				
			||||||
 | 
					                                dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
				
			||||||
 | 
					                            items.Add(dicListVal);
 | 
				
			||||||
 | 
					                            sb.Clear();
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    var parentNavs = new List<string>();
 | 
				
			||||||
 | 
					                    foreach (var navProp in tbref2.Properties)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue;
 | 
				
			||||||
 | 
					                        if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue;
 | 
				
			||||||
 | 
					                        var tr2ref = tbref2.GetTableRef(navProp.Key, false);
 | 
				
			||||||
 | 
					                        if (tr2ref == null) continue;
 | 
				
			||||||
 | 
					                        if (tr2ref.RefType != TableRefType.ManyToOne) continue;
 | 
				
			||||||
 | 
					                        if (tr2ref.RefEntityType != tb.Type) continue;
 | 
				
			||||||
 | 
					                        parentNavs.Add(navProp.Key);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    foreach (var nav in subList)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        string key = null;
 | 
				
			||||||
 | 
					                        if (tbref.RefColumns.Count == 1)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString();
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var sb = new StringBuilder();
 | 
				
			||||||
 | 
					                            for (var z = 0; z < tbref.RefColumns.Count; z++)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if (z > 0) sb.Append("*$*");
 | 
				
			||||||
 | 
					                                sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[z].CsName));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            key = sb.ToString();
 | 
				
			||||||
 | 
					                            sb.Clear();
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        if (dicList.TryGetValue(key, out var t1items) == false) continue;
 | 
				
			||||||
 | 
					                        foreach (var t1item in t1items)
 | 
				
			||||||
 | 
					                            t1item.Item2.Add(nav);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        //将子集合的,多对一,对象设置为当前对象
 | 
				
			||||||
 | 
					                        foreach (var parentNav in parentNavs)
 | 
				
			||||||
 | 
					                            foreach (var t1item in t1items)
 | 
				
			||||||
 | 
					                                _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    foreach (var t1items in dicList.Values)
 | 
				
			||||||
 | 
					                        foreach (var t1item in t1items)
 | 
				
			||||||
 | 
					                            setListValue(t1item.Item1, t1item.Item2);
 | 
				
			||||||
 | 
					                    dicList.Clear();
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (tbref.RefType ==  TableRefType.OneToMany && _includeManySubListOneToManyTempValue1 != null && _includeManySubListOneToManyTempValue1 is List<TNavigate>)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    fillOneToManyData(_includeManySubListOneToManyTempValue1 as List<TNavigate>, _commonUtils.GetTableByEntity(tbref.RefEntityType));
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var subSelect = _orm.Select<TNavigate>()
 | 
					                var subSelect = _orm.Select<TNavigate>()
 | 
				
			||||||
                    .DisableGlobalFilter()
 | 
					                    .DisableGlobalFilter()
 | 
				
			||||||
                    .WithConnection(_connection)
 | 
					                    .WithConnection(_connection)
 | 
				
			||||||
@@ -794,83 +881,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            if (subList.Any() == false)
 | 
					                            fillOneToManyData(subList, tbref2);
 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                foreach (var item in list)
 | 
					 | 
				
			||||||
                                    setListValue(item, new List<TNavigate>());
 | 
					 | 
				
			||||||
                                return;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            Dictionary<string, List<Tuple<T1, List<TNavigate>>>> dicList = new Dictionary<string, List<Tuple<T1, List<TNavigate>>>>();
 | 
					 | 
				
			||||||
                            foreach (var item in list)
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                if (tbref.Columns.Count == 1)
 | 
					 | 
				
			||||||
                                {
 | 
					 | 
				
			||||||
                                    var dicListKey = getListValue(item, tbref.Columns[0].CsName, 0)?.ToString();
 | 
					 | 
				
			||||||
                                    if (dicListKey == null) continue;
 | 
					 | 
				
			||||||
                                    var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
					 | 
				
			||||||
                                    if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
					 | 
				
			||||||
                                        dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
					 | 
				
			||||||
                                    items.Add(dicListVal);
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                else
 | 
					 | 
				
			||||||
                                {
 | 
					 | 
				
			||||||
                                    var sb = new StringBuilder();
 | 
					 | 
				
			||||||
                                    for (var z = 0; z < tbref.Columns.Count; z++)
 | 
					 | 
				
			||||||
                                    {
 | 
					 | 
				
			||||||
                                        if (z > 0) sb.Append("*$*");
 | 
					 | 
				
			||||||
                                        sb.Append(getListValue(item, tbref.Columns[z].CsName, z));
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    var dicListKey = sb.ToString();
 | 
					 | 
				
			||||||
                                    var dicListVal = Tuple.Create(item, new List<TNavigate>());
 | 
					 | 
				
			||||||
                                    if (dicList.TryGetValue(dicListKey, out var items) == false)
 | 
					 | 
				
			||||||
                                        dicList.Add(dicListKey, items = new List<Tuple<T1, List<TNavigate>>>());
 | 
					 | 
				
			||||||
                                    items.Add(dicListVal);
 | 
					 | 
				
			||||||
                                    sb.Clear();
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            var parentNavs = new List<string>();
 | 
					 | 
				
			||||||
                            foreach (var navProp in tbref2.Properties)
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                if (tbref2.ColumnsByCs.ContainsKey(navProp.Key)) continue;
 | 
					 | 
				
			||||||
                                if (tbref2.ColumnsByCsIgnore.ContainsKey(navProp.Key)) continue;
 | 
					 | 
				
			||||||
                                var tr2ref = tbref2.GetTableRef(navProp.Key, false);
 | 
					 | 
				
			||||||
                                if (tr2ref == null) continue;
 | 
					 | 
				
			||||||
                                if (tr2ref.RefType != TableRefType.ManyToOne) continue;
 | 
					 | 
				
			||||||
                                if (tr2ref.RefEntityType != tb.Type) continue;
 | 
					 | 
				
			||||||
                                parentNavs.Add(navProp.Key);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            foreach (var nav in subList)
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                string key = null;
 | 
					 | 
				
			||||||
                                if (tbref.RefColumns.Count == 1)
 | 
					 | 
				
			||||||
                                {
 | 
					 | 
				
			||||||
                                    key = _orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[0].CsName).ToString();
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                else
 | 
					 | 
				
			||||||
                                {
 | 
					 | 
				
			||||||
                                    var sb = new StringBuilder();
 | 
					 | 
				
			||||||
                                    for (var z = 0; z < tbref.RefColumns.Count; z++)
 | 
					 | 
				
			||||||
                                    {
 | 
					 | 
				
			||||||
                                        if (z > 0) sb.Append("*$*");
 | 
					 | 
				
			||||||
                                        sb.Append(_orm.GetEntityValueWithPropertyName(tbref.RefEntityType, nav, tbref.RefColumns[z].CsName));
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                    key = sb.ToString();
 | 
					 | 
				
			||||||
                                    sb.Clear();
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                if (dicList.TryGetValue(key, out var t1items) == false) return;
 | 
					 | 
				
			||||||
                                foreach (var t1item in t1items)
 | 
					 | 
				
			||||||
                                    t1item.Item2.Add(nav);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                //将子集合的,多对一,对象设置为当前对象
 | 
					 | 
				
			||||||
                                foreach (var parentNav in parentNavs)
 | 
					 | 
				
			||||||
                                    foreach (var t1item in t1items)
 | 
					 | 
				
			||||||
                                        _orm.SetEntityValueWithPropertyName(tbref.RefMiddleEntityType, nav, parentNav, t1item.Item1);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            foreach (var t1items in dicList.Values)
 | 
					 | 
				
			||||||
                                foreach (var t1item in t1items)
 | 
					 | 
				
			||||||
                                    setListValue(t1item.Item1, t1item.Item2);
 | 
					 | 
				
			||||||
                            dicList.Clear();
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    case TableRefType.ManyToMany:
 | 
					                    case TableRefType.ManyToMany:
 | 
				
			||||||
@@ -1044,7 +1055,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                                    key = sb.ToString();
 | 
					                                    key = sb.ToString();
 | 
				
			||||||
                                    sb.Clear();
 | 
					                                    sb.Clear();
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                if (dicList.TryGetValue(key, out var t1items) == false) return;
 | 
					                                if (dicList.TryGetValue(key, out var t1items) == false) continue;
 | 
				
			||||||
                                foreach (var t1item in t1items)
 | 
					                                foreach (var t1item in t1items)
 | 
				
			||||||
                                    t1item.Item2.Add(subList[a]);
 | 
					                                    t1item.Item2.Add(subList[a]);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
@@ -1065,6 +1076,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal object _includeManySubListOneToManyTempValue1 = null;
 | 
				
			||||||
        internal void SetList(IEnumerable<T1> list)
 | 
					        internal void SetList(IEnumerable<T1> list)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            foreach (var include in _includeToList) include?.Invoke(list);
 | 
					            foreach (var include in _includeToList) include?.Invoke(list);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user