mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 增加 IncludeByPropertyName 按属性名进行 Include/IncludeMany 操作;#278
This commit is contained in:
		@@ -2345,6 +2345,13 @@
 | 
			
		||||
            <param name="then">即能 ThenInclude,还可以二次过滤(这个 EFCore 做不到?)</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ISelect`1.IncludeByPropertyName(System.String)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            按属性名字符串进行 Include/IncludeMany 操作
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="property"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ISelect`1.WithSql(System.String,System.Object)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            实现 select .. from ( select ... from t ) a 这样的功能<para></para>
 | 
			
		||||
 
 | 
			
		||||
@@ -333,6 +333,13 @@ namespace FreeSql
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavigate>>> navigateSelector, Action<ISelect<TNavigate>> then = null) where TNavigate : class;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 按属性名字符串进行 Include/IncludeMany 操作
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="property"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        ISelect<T1> IncludeByPropertyName(string property);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 实现 select .. from ( select ... from t ) a 这样的功能<para></para>
 | 
			
		||||
        /// 使用 AsTable 方法也可以达到效果<para></para>
 | 
			
		||||
 
 | 
			
		||||
@@ -121,13 +121,13 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            to._whereGlobalFilter = new List<GlobalFilter.Item>(from._whereGlobalFilter.ToArray());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Expression ConvertStringPropertyToExpression(string property)
 | 
			
		||||
        public Expression ConvertStringPropertyToExpression(string property, bool fromFirstTable = false)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(property)) return null;
 | 
			
		||||
            var field = property.Split('.').Select(a => a.Trim()).ToArray();
 | 
			
		||||
            Expression exp = null;
 | 
			
		||||
 | 
			
		||||
            if (field.Length == 1)
 | 
			
		||||
            if (field.Length == 1 && fromFirstTable == false)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var tb in _tables)
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -392,6 +392,36 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
 | 
			
		||||
        public int InsertInto<TTargetEntity>(string tableName, Expression<Func<T1, TTargetEntity>> select) where TTargetEntity : class => base.InternalInsertInto<TTargetEntity>(tableName, select);
 | 
			
		||||
 | 
			
		||||
        public ISelect<T1> IncludeByPropertyName(string property)
 | 
			
		||||
        {
 | 
			
		||||
            var exp = ConvertStringPropertyToExpression(property, true);
 | 
			
		||||
            if (exp == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树");
 | 
			
		||||
            var memExp = exp as MemberExpression;
 | 
			
		||||
            if (memExp == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树2");
 | 
			
		||||
            var parTb = _commonUtils.GetTableByEntity(memExp.Expression.Type);
 | 
			
		||||
            if (parTb == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树3");
 | 
			
		||||
            var parTbref = parTb.GetTableRef(memExp.Member.Name, true);
 | 
			
		||||
            if (parTbref == null) throw new ArgumentException($"{nameof(property)} 不是有效的导航属性");
 | 
			
		||||
            switch (parTbref.RefType)
 | 
			
		||||
            {
 | 
			
		||||
                case TableRefType.ManyToMany:
 | 
			
		||||
                case TableRefType.OneToMany:
 | 
			
		||||
                    var funcType = typeof(Func<,>).MakeGenericType(_tables[0].Table.Type, typeof(IEnumerable<>).MakeGenericType(parTbref.RefEntityType));
 | 
			
		||||
                    var navigateSelector = Expression.Lambda(funcType, exp, _tables[0].Parameter);
 | 
			
		||||
                    var incMethod = this.GetType().GetMethod("IncludeMany");
 | 
			
		||||
                    if (incMethod == null) throw new Exception("运行时错误,反射获取 IncludeMany 方法失败");
 | 
			
		||||
                    incMethod.MakeGenericMethod(parTbref.RefEntityType).Invoke(this, new object[] { navigateSelector, null });
 | 
			
		||||
                    break;
 | 
			
		||||
                case TableRefType.ManyToOne:
 | 
			
		||||
                case TableRefType.OneToOne:
 | 
			
		||||
                    _isIncluded = true;
 | 
			
		||||
                    var curTb = _commonUtils.GetTableByEntity(exp.Type);
 | 
			
		||||
                    _commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(exp, curTb.Properties[curTb.ColumnsByCs.First().Value.CsName]), null, null, null);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool _isIncluded = false;
 | 
			
		||||
        public ISelect<T1> Include<TNavigate>(Expression<Func<T1, TNavigate>> navigateSelector) where TNavigate : class
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user