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)); }