Exemple #1
0
        public virtual IEnumerable <T> ExecuteSubQuery <T>(LambdaExpression query, IDataReader dataReader)
        {
            var projection = (SqlProjectionExpression)query.Body;

            var expectedSelector = "GROUPBYCOLUMNS-" + projection.Select.Alias;

            projection = (SqlProjectionExpression)ExpressionReplacer.Replace(projection, c =>
            {
                if (query.Parameters[0] == c)
                {
                    return(Expression.Constant(this));
                }

                var column = c as SqlColumnExpression;

                if (column != null && column.SelectAlias.StartsWith(expectedSelector))
                {
                    var sqlDataTypeProvider = this.SqlDatabaseContext.SqlDataTypeProvider.GetSqlDataType(column.Type);

                    var parameter = Expression.Parameter(typeof(IDataReader));
                    var func      = Expression.Lambda <Func <IDataReader, object> >(Expression.Convert(sqlDataTypeProvider.GetReadExpression(parameter, dataReader.GetOrdinal(column.Name)), typeof(object)), parameter).Compile();

                    var value = func(dataReader);

                    return(Expression.Constant(value, column.Type));
                }

                return(null);
            });

            projection = (SqlProjectionExpression)SqlQueryProvider.Optimize(projection, this.SqlDatabaseContext.SqlDataTypeProvider.GetTypeForEnums(), true);

            return(this.provider.CreateQuery <T>(projection));
        }
        private Expression BuildIndexExpression(TypeDescriptor typeDescriptor, SqlTableExpression table, IndexInfo indexInfo)
        {
            Expression where = null;

            var indexedColumns = new List <SqlIndexedColumnExpression>();

            foreach (var property in indexInfo.Properties.Where(c => !c.IncludeOnly))
            {
                foreach (var columnInfo in QueryBinder.GetColumnInfos(this.model.TypeDescriptorProvider, typeDescriptor.GetPropertyDescriptorByPropertyName(property.PropertyName)))
                {
                    indexedColumns.Add(new SqlIndexedColumnExpression(new SqlColumnExpression(columnInfo.DefinitionProperty.PropertyType, null, columnInfo.ColumnName), property.SortOrder, property.Lowercase));
                }
            }

            var includedColumns = new List <SqlIndexedColumnExpression>();

            foreach (var property in indexInfo.Properties.Where(c => c.IncludeOnly))
            {
                foreach (var columnInfo in QueryBinder.GetColumnInfos(this.model.TypeDescriptorProvider, typeDescriptor.GetPropertyDescriptorByPropertyName(property.PropertyName)))
                {
                    includedColumns.Add(new SqlIndexedColumnExpression(new SqlColumnExpression(columnInfo.DefinitionProperty.PropertyType, null, columnInfo.ColumnName)));
                }
            }

            var parameterExpression = Expression.Parameter(typeDescriptor.Type);

            if (indexInfo.Condition == null)
            {
                foreach (var property in indexInfo.Properties.Where(c => !c.Condition.IsNullOrEmpty()))
                {
                    var expression = ComputedExpressionParser.Parse(property.Condition, typeDescriptor.GetPropertyDescriptorByPropertyName(property.PropertyName), parameterExpression, null, typeof(bool));

                    if (expression == null)
                    {
                        continue;
                    }

                    where = where == null ? expression.Body : Expression.And(where, expression.Body);
                }
            }
            else
            {
                where = ComputedExpressionParser.Parse(indexInfo.Condition, parameterExpression, null, typeof(bool)).Body;
            }

            if (where != null)
            {
                where = Expression.Lambda(where, parameterExpression);

                var call = Expression.Call(null, MethodInfoFastRef.QueryableWhereMethod.MakeGenericMethod(parameterExpression.Type), Expression.Constant(null, typeof(DataAccessObjects <>).MakeGenericType(parameterExpression.Type)), where);

                var projection = (SqlProjectionExpression)SqlQueryProvider.Optimize(this.dataAccessModel, SqlQueryProvider.Bind(this.dataAccessModel, this.sqlDataTypeProvider, call));

                where = projection.Select.Where;

                where = SqlAliasReferenceReplacer.Replace(where, ((SqlAliasedExpression)projection.Select.From).Alias, null);
            }

            return(new SqlCreateIndexExpression(indexInfo.IndexName, table, indexInfo.Unique, indexInfo.IndexType, false, indexedColumns, includedColumns, where));
        }
        private Expression BuildIndexExpression(SqlTableExpression table, string indexName, Tuple <IndexAttribute, PropertyDescriptor>[] properties)
        {
            Expression where = null;
            var unique         = properties.Select(c => c.Item1).Any(c => c.Unique);
            var lowercaseIndex = properties.Any(c => c.Item1.LowercaseIndex);
            var indexType      = properties.Select(c => c.Item1.IndexType).FirstOrDefault(c => c != IndexType.Default);
            var sorted         = properties.OrderBy(c => c.Item1.CompositeOrder, Comparer <int> .Default);

            var indexedColumns = new List <SqlIndexedColumnExpression>();

            foreach (var attributeAndProperty in sorted.Where(c => !c.Item1.IncludeOnly))
            {
                foreach (var columnInfo in QueryBinder.GetColumnInfos(this.model.TypeDescriptorProvider, attributeAndProperty.Item2))
                {
                    indexedColumns.Add(new SqlIndexedColumnExpression(new SqlColumnExpression(columnInfo.DefinitionProperty.PropertyType, null, columnInfo.ColumnName), attributeAndProperty.Item1.SortOrder, attributeAndProperty.Item1.LowercaseIndex));
                }
            }

            var includedColumns = new List <SqlIndexedColumnExpression>();

            foreach (var attributeAndProperty in sorted.Where(c => c.Item1.IncludeOnly))
            {
                foreach (var columnInfo in QueryBinder.GetColumnInfos(this.model.TypeDescriptorProvider, attributeAndProperty.Item2))
                {
                    includedColumns.Add(new SqlIndexedColumnExpression(new SqlColumnExpression(columnInfo.DefinitionProperty.PropertyType, null, columnInfo.ColumnName)));
                }
            }

            Debug.Assert(properties.Select(c => c.Item2.PropertyInfo.DeclaringType).Distinct().Count() == 1);

            var parameterExpression = Expression.Parameter(properties.First().Item2.PropertyInfo.DeclaringType);

            foreach (var attributeAndProperty in sorted.Where(c => !c.Item1.Condition.IsNullOrEmpty()))
            {
                var expression = ComputedExpressionParser.Parse(attributeAndProperty.Item1.Condition, attributeAndProperty.Item2, parameterExpression, null, typeof(bool));

                if (expression == null)
                {
                    continue;
                }

                where = where == null ? expression.Body : Expression.And(where, expression.Body);
            }

            if (where != null)
            {
                where = Expression.Lambda(where, parameterExpression);

                var call = Expression.Call(null, MethodInfoFastRef.QueryableWhereMethod.MakeGenericMethod(parameterExpression.Type), Expression.Constant(null, typeof(DataAccessObjects <>).MakeGenericType(parameterExpression.Type)), where);

                var projection = (SqlProjectionExpression)SqlQueryProvider.Optimize(this.dataAccessModel, SqlQueryProvider.Bind(this.dataAccessModel, this.sqlDataTypeProvider, call));

                where = projection.Select.Where;

                where = AliasReferenceReplacer.Replace(where, ((SqlTableExpression)projection.Select.From).Alias, null);
            }

            return(new SqlCreateIndexExpression(indexName, table, unique, lowercaseIndex, indexType, false, indexedColumns, includedColumns, where));
        }