Example #1
0
        protected override Expression VisitConstant(ConstantExpression c)
        {
            if (c.Value is IQueryable queryable && queryable.Provider == _provider)
            {
                Type elementType = queryable.ElementType;
                AliasedExpression source;
                if (typeof(Table <>).MakeGenericType(elementType) == queryable.GetType())
                {
                    var nameProperty = queryable.GetType().GetRuntimeProperty("Name");
                    source = new TableExpression(GetNewAlias(), (string)nameProperty.GetValue(queryable));
                }
                else if (typeof(View <>).MakeGenericType(elementType) == queryable.GetType())
                {
                    var nameProperty = queryable.GetType().GetRuntimeProperty("Name");
                    source = new TableExpression(GetNewAlias(), (string)nameProperty.GetValue(queryable));
                }
                else
                {
                    return(Visit(queryable.Expression));
                }

                string selectAlias = GetNewAlias();

                List <MemberBinding>     bindings = new List <MemberBinding>();
                List <ColumnDeclaration> columns  = new List <ColumnDeclaration>();

                foreach (PropertyInfo pi in elementType.GetRuntimeProperties().Where(pi => !pi.IsDefined(typeof(IgnoreAttribute))))
                {
                    string columnName = Orm.GetColumnName(pi);
                    Type   columnType = pi.PropertyType;

                    bindings.Add(Expression.Bind(pi, new ColumnExpression(columnType, selectAlias, columnName)));
                    columns.Add(new ColumnDeclaration(columnName, new ColumnExpression(columnType, source.Alias, columnName)));
                }

                return(new ProjectionExpression(
                           new SelectExpression(selectAlias, columns, source),
                           Expression.MemberInit(Expression.New(elementType), bindings)
                           ));
            }
            return(c);
        }