Exemple #1
0
            public static IEnumerable <TableRefTree> GetTableRefTree(IFreeSql orm, TableRefTree tree, int maxLevel, string[] properties = null)
            {
                if (tree.Level > maxLevel)
                {
                    yield break;
                }
                var tableRefs = tree.TableInfo.Properties.Where(property => properties == null || string.Equals(properties[tree.Level - 1], property.Key, StringComparison.OrdinalIgnoreCase)).Select(a => tree.TableInfo.GetTableRef(a.Key, false)).Where(a => a != null).ToList();

                foreach (var tableRef in tableRefs)
                {
                    var tableInfo = orm.CodeFirst.GetTableByEntity(tableRef.RefEntityType);
                    var sub       = new TableRefTree()
                    {
                        Level     = tree.Level + 1,
                        TableInfo = tableInfo,
                        TableRef  = tableRef,
                        Parent    = tree,
                    };

                    // 排除重复类型
                    if (sub.CheckRepeat())
                    {
                        continue;
                    }

                    sub.Subs = GetTableRefTree(orm, sub, maxLevel, properties).ToList();
                    yield return(sub);
                }
            }
Exemple #2
0
        public static Expression <Func <T1, bool> > GetWhereExpression <T1>(ISelect <T1> select, DynamicFilterInfo filter)
        {
            var properties = filter.Field.Split('.');
            var tree       = TableRefTree.GetTableRefTree(select, properties.Length, properties);

            // 检索
            var treeList        = GetTreeList(tree).ToList();
            var deepest         = treeList.Last();
            var collectionNodes = treeList.Where(a => a.TableRef.RefType == TableRefType.OneToMany || a.TableRef.RefType == TableRefType.ManyToMany).ToList();

            if (deepest.Level != properties.Length)
            {
                throw new Exception($"当前类型{typeof(T1)}导航属性{filter.Field}匹配检索失败");
            }
            if (collectionNodes.Count == 0)
            {
                throw new Exception($"当前类型{typeof(T1)}导航属性{filter.Field}不包含{TableRefType.OneToMany}或者{nameof(TableRefType.ManyToMany)}关系");
            }

            var selectMethod        = typeof(FreeSqlGlobalExtensions).GetMethods().First(a => a.ContainsGenericParameters && a.GetParameters().Count() == 1);
            var parameterExpression = Expression.Parameter(typeof(T1), "t");
            var manyLevel           = 0;
            var exp = GetWhereExpression(select, deepest, filter, properties, null, ref manyLevel);

            return(exp as Expression <Func <T1, bool> >);
        }
Exemple #3
0
            public static TableRefTree GetTableRefTree <T1>(ISelect <T1> select, int maxLevel, string[] properties = null)
            {
                var orm       = select.GetType().GetField("_orm").GetValue(select) as IFreeSql;
                var tableInfo = orm.CodeFirst.GetTableByEntity(typeof(T1));
                var tree      = new TableRefTree()
                {
                    Level     = 1,
                    TableInfo = tableInfo,
                };

                tree.Subs = GetTableRefTree(orm, tree, maxLevel, properties).ToList();
                return(tree);
            }
Exemple #4
0
        private static IEnumerable <TableRefTree> GetTreeList(TableRefTree tree)
        {
            if (tree.Subs == null || tree.Subs.Count == 0)
            {
                yield break;
            }
            yield return(tree.Subs[0]);

            foreach (var sub in GetTreeList(tree.Subs[0]))
            {
                yield return(sub);
            }
        }
Exemple #5
0
 static bool CheckRepeat(this TableRefTree tree, List <Type> types = null)
 {
     if (tree.Parent == null)
     {
         return(false);
     }
     if (types == null)
     {
         types = new List <System.Type> {
             tree.TableInfo.Type
         };
         return(CheckRepeat(tree.Parent, types));
     }
     return(types.Contains(tree.TableInfo.Type) || CheckRepeat(tree.Parent, types));
 }
Exemple #6
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);
        }
Exemple #7
0
        public static ISelect <T1> IncludeLevel <T1>(this ISelect <T1> select, int level)
        {
            var tree = TableRefTree.GetTableRefTree(select, level);

            return(select.IncludeLevel(level, tree));
        }
Exemple #8
0
        private static Expression GetWhereExpression <T1>(ISelect <T1> select, TableRefTree deepest, DynamicFilterInfo filterInfo, string[] properties, Expression body, ref int manyLevel)
        {
            while (deepest.Parent != null && deepest.TableRef.RefType != TableRefType.ManyToMany && deepest.TableRef.RefType != TableRefType.OneToMany)
            {
                deepest = deepest.Parent;
            }
            manyLevel++;
            if (manyLevel == 1)
            {
                filterInfo = new DynamicFilterInfo
                {
                    Field    = string.Join(".", properties.Skip(deepest.Level - 1)),
                    Operator = filterInfo.Operator,
                    Value    = filterInfo.Value,
                };
                deepest = deepest.Parent;
                return(GetWhereExpression(select, deepest, filterInfo, properties, body, ref manyLevel));
            }
            if (body == null)
            {
                body = Expression.Parameter(deepest.TableInfo.Type, $"t{deepest.Level}");
                var sub = deepest;
                do
                {
                    sub  = sub.Subs.First();
                    body = Expression.Property(body, sub.TableRef.Property);
                } while (sub.TableRef.RefType != TableRefType.ManyToMany && sub.TableRef.RefType != TableRefType.OneToMany);

                var selectMethod = typeof(FreeSqlGlobalExtensions).GetMethods().First(a => a.Name == "AsSelect" && a.ContainsGenericParameters && a.GetParameters().Count() == 1).MakeGenericMethod(sub.TableRef.RefEntityType);
                body = Expression.Call(null, selectMethod, body);
                var asMethod        = typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType).GetMethod("As");
                var constExpression = Expression.Constant($"t{deepest.Level}");
                body = Expression.Call(body, asMethod, constExpression);
                var whereDynamicFilterMethod = typeof(ISelect0 <,>).MakeGenericType(typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType), sub.TableRef.RefEntityType).GetMethod("WhereDynamicFilter");
                body = Expression.Call(body, whereDynamicFilterMethod, Expression.Constant(filterInfo));
                var anyMethod = typeof(ISelect0 <,>).MakeGenericType(typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType), sub.TableRef.RefEntityType).GetMethod("Any");
                body = Expression.Call(body, anyMethod);

                deepest = deepest.Parent;
            }
            else
            {
                Expression subBody = Expression.Parameter(deepest.TableInfo.Type, $"t{deepest.Level}");
                var        sub     = deepest;
                do
                {
                    sub     = sub.Subs.First();
                    subBody = Expression.Property(subBody, sub.TableRef.Property);
                } while (sub.TableRef.RefType != TableRefType.ManyToMany && sub.TableRef.RefType != TableRefType.OneToMany);

                var selectMethod = typeof(FreeSqlGlobalExtensions).GetMethods().First(a => a.Name == "AsSelect" && a.ContainsGenericParameters && a.GetParameters().Count() == 1).MakeGenericMethod(sub.TableRef.RefEntityType);
                subBody = Expression.Call(null, selectMethod, subBody);
                var anyMethod = typeof(ISelect <>).MakeGenericType(sub.TableRef.RefEntityType).GetMethod("Any");

                var funcType      = typeof(Func <,>).MakeGenericType(sub.TableRef.RefEntityType, typeof(bool));
                var parameterBody = Expression.Parameter(sub.TableInfo.Type, $"t{sub.Level}");
                var lambda        = Expression.Lambda(funcType, body, parameterBody);
                body = Expression.Call(subBody, anyMethod, lambda);

                deepest = deepest.Parent;
            }

            if (deepest == null)
            {
                var funcType      = typeof(Func <,>).MakeGenericType(typeof(T1), typeof(bool));
                var parameterBody = Expression.Parameter(typeof(T1), "t1");
                return(Expression.Lambda(funcType, body, parameterBody));
            }
            else
            {
                return(GetWhereExpression(select, deepest, filterInfo, properties, body, ref manyLevel));
            }
        }