示例#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));
        }
示例#2
0
        public static IQueryable CreateQuery(Type elementType, SqlQueryProvider provider, Expression expression)
        {
            Func <SqlQueryProvider, Expression, IQueryable> func;

            if (!createQueryCache.TryGetValue(elementType.TypeHandle, out func))
            {
                var providerParam   = Expression.Parameter(typeof(SqlQueryProvider));
                var expressionParam = Expression.Parameter(typeof(Expression));

                func = Expression.Lambda <Func <SqlQueryProvider, Expression, IQueryable> >(Expression.New
                                                                                            (
                                                                                                TypeUtils.GetConstructor(() => new SqlQueryable <object>(null, null)).GetConstructorOnTypeReplacingTypeGenericArgs(elementType),
                                                                                                providerParam,
                                                                                                expressionParam
                                                                                            ), providerParam, expressionParam).Compile();

                var newCreateQueryCache = new Dictionary <RuntimeTypeHandle, Func <SqlQueryProvider, Expression, IQueryable> >(createQueryCache)
                {
                    [elementType.TypeHandle] = func
                };

                createQueryCache = newCreateQueryCache;
            }

            return(func(provider, expression));
        }
示例#3
0
 public ObjectProjector(SqlQueryProvider queryProvider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryFormatResult formatResult)
 {
     this.QueryProvider      = queryProvider;
     this.DataAccessModel    = dataAccessModel;
     this.SqlDatabaseContext = sqlDatabaseContext;
     this.formatResult       = formatResult;
 }
        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));
        }
示例#6
0
 public ObjectProjector(SqlQueryProvider queryProvider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, string commandText, IReadOnlyList <TypedValue> parameterValues)
 {
     this.QueryProvider      = queryProvider;
     this.DataAccessModel    = dataAccessModel;
     this.SqlDatabaseContext = sqlDatabaseContext;
     this.CommandText        = commandText;
     this.ParameterValues    = parameterValues;
 }
示例#7
0
 public ExecutionBuildResult(SqlQueryProvider sqlQueryProvider, SqlQueryFormatResult formatResult, Delegate projector, Delegate asyncProjector, object[] arguments)
     : this()
 {
     this.SqlQueryProvider = sqlQueryProvider;
     this.Arguments        = arguments;
     this.Projector        = projector;
     this.AsyncProjector   = asyncProjector;
     this.FormatResult     = formatResult;
 }
示例#8
0
        private ProjectionBuilder(DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryProvider queryProvider, ProjectionBuilderScope scope)
        {
            this.dataAccessModel    = dataAccessModel;
            this.sqlDatabaseContext = sqlDatabaseContext;
            this.queryProvider      = queryProvider;

            this.scope = scope;

            this.dataReader        = Expression.Parameter(typeof(IDataReader), "dataReader");
            this.objectProjector   = Expression.Parameter(typeof(ObjectProjector), "objectProjector");
            this.dynamicParameters = Expression.Parameter(typeof(object[]), "dynamicParameters");
            this.versionParameter  = Expression.Parameter(typeof(int), "version");
        }
示例#9
0
        public static IQueryable CreateQuery(Type elementType, SqlQueryProvider provider, Expression expression)
        {
            if (!createQueryCache.TryGetValue(elementType.TypeHandle, out var func))
            {
                var providerParam   = Expression.Parameter(typeof(SqlQueryProvider));
                var expressionParam = Expression.Parameter(typeof(Expression));

                func = Expression.Lambda <Func <SqlQueryProvider, Expression, IQueryable> >(Expression.New
                                                                                            (
                                                                                                TypeUtils.GetConstructor(() => new SqlQueryable <object>(null, null)).GetConstructorOnTypeReplacingTypeGenericArgs(elementType),
                                                                                                providerParam,
                                                                                                expressionParam
                                                                                            ), providerParam, expressionParam).Compile();

                createQueryCache = createQueryCache.Clone(elementType.TypeHandle, func, "createQueryCache");
            }

            return(func(provider, expression));
        }
示例#10
0
 public SqlQueryable(SqlQueryProvider provider, Expression expression)
     : base(provider, expression)
 {
 }
示例#11
0
 public DataAccessObjectContainerProjector(SqlQueryProvider provider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryFormatResult formatResult, object[] placeholderValues, Func <ObjectProjector, IDataReader, int, object[], Func <DataAccessObject, DataAccessObject>, U> objectReader)
     : base(provider, dataAccessModel, sqlDatabaseContext, formatResult, placeholderValues, objectReader)
 {
     outputComparer = DataAccessObjectAwareResultTypeComparerBuilder.CreateComparer <T>();
 }
 public ComplexDataAccessObjectProjector(SqlQueryProvider provider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, string commandText, IReadOnlyList <TypedValue> parameterValues, object[] placeholderValues, ObjectReaderFunc <T> objectReader, Func <IDataReader, object[]> keysGenerator)
     : base(provider, dataAccessModel, sqlDatabaseContext, commandText, parameterValues, placeholderValues, objectReader)
 {
     this.keysGenerator = keysGenerator;
 }
示例#13
0
        public static LambdaExpression Build(DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryProvider queryProvider, Expression expression, ProjectionBuilderScope scope, out Expression <Func <IDataReader, object[]> > rootKeys)
        {
            var projectionBuilder = new ProjectionBuilder(dataAccessModel, sqlDatabaseContext, queryProvider, scope);

            var body = projectionBuilder.Visit(expression);

            if (projectionBuilder.scope.rootPrimaryKeys.Count > 0)
            {
                rootKeys = Expression.Lambda <Func <IDataReader, object[]> >(Expression.NewArrayInit(typeof(object), projectionBuilder.scope.rootPrimaryKeys), projectionBuilder.dataReader);
            }
            else
            {
                rootKeys = null;
            }

            return(Expression.Lambda(typeof(ObjectReaderFunc <>).MakeGenericType(body.Type), body, projectionBuilder.objectProjector, projectionBuilder.dataReader, projectionBuilder.versionParameter, projectionBuilder.dynamicParameters));
        }
示例#14
0
 public AlwaysReadFirstObjectProjector(SqlQueryProvider queryProvider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, string commandText, IReadOnlyList <TypedValue> parameterValues, object[] placeholderValues, ObjectReaderFunc <T> objectReader)
     : base(queryProvider, dataAccessModel, sqlDatabaseContext, commandText, parameterValues, placeholderValues, objectReader)
 {
 }
 public ComplexDataAccessObjectProjector(SqlQueryProvider provider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryFormatResult formatResult, object[] placeholderValues, Func <ObjectProjector, IDataReader, int, object[], Func <DataAccessObject, DataAccessObject>, U> objectReader, Func <IDataReader, object[]> keysGenerator)
     : base(provider, dataAccessModel, sqlDatabaseContext, formatResult, placeholderValues, objectReader)
 {
     this.keysGenerator = keysGenerator;
 }
 public DataAccessObjectProjector(SqlQueryProvider provider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryFormatResult formatResult, object[] placeholderValues, Func <ObjectProjector, IDataReader, int, object[], U> objectReader)
     : base(provider, dataAccessModel, sqlDatabaseContext, formatResult, placeholderValues, objectReader)
 {
 }
示例#17
0
        public static LambdaExpression Build(DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryProvider queryProvider, Expression expression, ProjectionBuilderScope scope)
        {
            var projectionBuilder = new ProjectionBuilder(dataAccessModel, sqlDatabaseContext, queryProvider, scope);

            var body = projectionBuilder.Visit(expression);

            return(Expression.Lambda(body, projectionBuilder.objectProjector, projectionBuilder.dataReader, projectionBuilder.versionParameter, projectionBuilder.dynamicParameters));
        }