Example #1
0
        private static ISelect <T1> IncludeLevel <T1>(this ISelect <T1> select, int level, TableRefTree tree, ParameterExpression parameterExpression = null, MemberExpression bodyExpression = null)
        {
            var includeMethod     = select.GetType().GetMethod("Include");
            var includeManyMethod = select.GetType().GetMethod("IncludeMany");

            parameterExpression ??= Expression.Parameter(tree.TableInfo.Type, "t");
            foreach (var sub in tree.Subs)
            {
                switch (sub.TableRef.RefType)
                {
                case TableRefType.ManyToOne:
                case TableRefType.OneToOne:
                {
                    var body = bodyExpression == null?Expression.Property(parameterExpression, sub.TableRef.Property) : Expression.Property(bodyExpression, sub.TableRef.Property);

                    if (sub.Subs.Count == 0)
                    {
                        var funcType         = typeof(Func <,>).MakeGenericType(parameterExpression.Type, sub.TableRef.RefEntityType);
                        var navigateSelector = Expression.Lambda(funcType, body, parameterExpression);
                        includeMethod.MakeGenericMethod(sub.TableRef.RefEntityType).Invoke(select, new object[] { navigateSelector });
                    }
                    else
                    {
                        select.IncludeLevel(level, sub, parameterExpression, body);
                    }
                }
                break;

                case TableRefType.ManyToMany:
                case TableRefType.OneToMany:
                {
                    var body = bodyExpression == null?Expression.Property(parameterExpression, sub.TableRef.Property) : Expression.Property(bodyExpression, sub.TableRef.Property);

                    object then = null;
                    if (sub.Subs.Count > 0)
                    {
                        //var thenSelectType = select.GetType().GetGenericTypeDefinition().MakeGenericType(sub.TableRef.RefEntityType);
                        var thenSelectType = typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType);
                        var thenType       = typeof(Action <>).MakeGenericType(thenSelectType);
                        var thenParameter  = Expression.Parameter(thenSelectType, "then");
                        var thenMethod     = typeof(FreeSql_1113_Extensions).GetMethod(nameof(IncludeLevel)).MakeGenericMethod(sub.TableRef.RefEntityType);
                        var thenLevelConst = Expression.Constant(level - sub.Level + 1);
                        var thenBody       = Expression.Call(null, thenMethod, thenParameter, thenLevelConst);
                        var thenExpression = Expression.Lambda(thenType, thenBody, thenParameter);
                        then = thenExpression.Compile();
                    }
                    var funcType         = typeof(Func <,>).MakeGenericType(parameterExpression.Type, typeof(IEnumerable <>).MakeGenericType(sub.TableRef.RefEntityType));
                    var navigateSelector = Expression.Lambda(funcType, body, parameterExpression);
                    includeManyMethod.MakeGenericMethod(sub.TableRef.RefEntityType).Invoke(select, new object[] { navigateSelector, then });
                }
                break;
                }
            }

            return(select);
        }
Example #2
0
        public static ISelect <T1> IncludeLevel <T1>(this ISelect <T1> select, int level)
        {
            var tree = TableRefTree.GetTableRefTree(select, level);

            return(select.IncludeLevel(level, tree));
        }