コード例 #1
0
        protected override Expression VisitProjection(SqlProjectionExpression projectionExpression)
        {
            if (typeof(RelatedDataAccessObjects <>).IsAssignableFromIgnoreGenericParameters(projectionExpression.Type))
            {
                var elementType = projectionExpression.Type.GetGenericArguments()[0];
                var originalPlaceholderCount = 0;
                var currentPlaceholderCount  = originalPlaceholderCount;

                var replacedExpressions = new List <Expression>();
                projectionExpression = (SqlProjectionExpression)SqlOuterQueryReferencePlaceholderSubstitutor.Substitute(projectionExpression, ref currentPlaceholderCount, replacedExpressions);
                var values = replacedExpressions.Select(c => Expression.Convert(this.Visit(c), typeof(object))).ToList();
                var where = projectionExpression.Select.Where;

                var typeDescriptor = this.dataAccessModel.TypeDescriptorProvider.GetTypeDescriptor(elementType);
                var columns        = QueryBinder.GetColumnInfos(this.dataAccessModel.TypeDescriptorProvider, typeDescriptor.PersistedProperties);

                var columnExpression = (SqlColumnExpression)SqlExpressionFinder.FindFirst(where, c => c.NodeType == (ExpressionType)SqlExpressionType.Column);
                var match            = columns.Single(d => d.ColumnName == columnExpression.Name);

                var reference = Expression.Call(Expression.Constant(this.dataAccessModel), MethodInfoFastRef.DataAccessModelGetReferenceByValuesMethod.MakeGenericMethod(match.ForeignType.Type), Expression.NewArrayInit(typeof(object), values));
                var property  = typeDescriptor.GetRelationshipInfos().Single(c => c.ReferencingProperty == match.RootProperty).TargetProperty;

                return(Expression.Convert(Expression.Property(reference, property), this.dataAccessModel.GetConcreteTypeFromDefinitionType(property.PropertyType)));
            }
            else
            {
                var currentPlaceholderCount = 0;
                var replacedExpressions     = new List <Expression>();
                projectionExpression = (SqlProjectionExpression)SqlOuterQueryReferencePlaceholderSubstitutor.Substitute(projectionExpression, ref currentPlaceholderCount, replacedExpressions);

                var newColumnIndexes = projectionExpression.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(d => d.Name, d => d.i);

                var savedScope = this.scope;
                this.scope = new ProjectionBuilderScope(newColumnIndexes);
                var projectionProjector = Expression.Lambda(this.Visit(projectionExpression.Projector), objectProjector, dataReader, versionParameter, dynamicParameters);
                this.scope = savedScope;

                var values = replacedExpressions.Select(c => (Expression)Expression.Convert(Visit(c), typeof(object))).ToList();

                var method = TypeUtils.GetMethod <SqlQueryProvider>(c => c.BuildExecution(default(SqlProjectionExpression), default(LambdaExpression), default(object[])));

                MethodInfo evaluate;

                if (projectionExpression.Type.GetSequenceElementType() == null)
                {
                    evaluate = MethodInfoFastRef.ExecutionBuildResultEvaluateMethod.MakeGenericMethod(projectionExpression.Type);
                }
                else
                {
                    evaluate = MethodInfoFastRef.ExecutionBuildResultEvaluateMethod.MakeGenericMethod(typeof(IEnumerable <>).MakeGenericType(projectionExpression.Type.GetSequenceElementType()));
                }

                return(Expression.Call(Expression.Call(Expression.Property(this.objectProjector, "QueryProvider"), method, Expression.Constant(projectionExpression), projectionProjector, Expression.NewArrayInit(typeof(object), values)), evaluate));
            }
        }
コード例 #2
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");
        }
コード例 #3
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");
			this.filterParameter = Expression.Parameter(typeof(Func<DataAccessObject, DataAccessObject>), "filter");
		}
コード例 #4
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(body, projectionBuilder.objectProjector, projectionBuilder.dataReader, projectionBuilder.versionParameter, projectionBuilder.dynamicParameters, projectionBuilder.filterParameter);
		}
コード例 #5
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));
        }
コード例 #6
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));
        }
コード例 #7
0
		protected override Expression VisitProjection(SqlProjectionExpression projectionExpression)
		{
			if (typeof(RelatedDataAccessObjects<>).IsAssignableFromIgnoreGenericParameters(projectionExpression.Type))
			{
				var elementType = projectionExpression.Type.GetGenericArguments()[0];
				var originalPlaceholderCount = 0;
				var currentPlaceholderCount = originalPlaceholderCount;

				var replacedExpressions = new List<Expression>();
				projectionExpression = (SqlProjectionExpression)SqlOuterQueryReferencePlaceholderSubstitutor.Substitute(projectionExpression, ref currentPlaceholderCount, replacedExpressions);
				var values = replacedExpressions.Select(c => Expression.Convert(this.Visit(c), typeof(object))).ToList();
				var where = projectionExpression.Select.Where;

				var typeDescriptor = this.dataAccessModel.TypeDescriptorProvider.GetTypeDescriptor(elementType);
				var columns = QueryBinder.GetColumnInfos(this.dataAccessModel.TypeDescriptorProvider, typeDescriptor.PersistedProperties);
				
				var columnExpression = (SqlColumnExpression)SqlExpressionFinder.FindFirst(where, c => c.NodeType == (ExpressionType)SqlExpressionType.Column);
				var match = columns.Single(d => d.ColumnName == columnExpression.Name);

				var reference = Expression.Call(Expression.Constant(this.dataAccessModel), MethodInfoFastRef.DataAccessModelGetReferenceByValuesMethod.MakeGenericMethod(match.ForeignType.Type), Expression.NewArrayInit(typeof(object), values));
				var property = typeDescriptor.GetRelationshipInfos().Single(c => c.ReferencingProperty == match.RootProperty).TargetProperty;

				return Expression.Convert(Expression.Property(reference, property), this.dataAccessModel.GetConcreteTypeFromDefinitionType(property.PropertyType));
			}
			else
			{
				var currentPlaceholderCount = 0;
				var replacedExpressions = new List<Expression>();
				projectionExpression = (SqlProjectionExpression)SqlOuterQueryReferencePlaceholderSubstitutor.Substitute(projectionExpression, ref currentPlaceholderCount, replacedExpressions);

				var newColumnIndexes = projectionExpression.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(d => d.Name, d => d.i);

				var savedScope = this.scope;
				this.scope = new ProjectionBuilderScope(newColumnIndexes);
				var projectionProjector = Expression.Lambda(this.Visit(projectionExpression.Projector), objectProjector, dataReader, versionParameter, dynamicParameters, filterParameter);

				Expression rootKeys;

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

				this.scope = savedScope;

				var values = replacedExpressions.Select(c => (Expression)Expression.Convert(Visit(c), typeof(object))).ToList();

				var method = TypeUtils.GetMethod<SqlQueryProvider>(c => c.BuildExecution(default(SqlProjectionExpression), default(LambdaExpression), default(object[]), default(Expression<Func<IDataReader, object[]>>)));

				MethodInfo evaluate;

				if (projectionExpression.Type.GetSequenceElementType() == null)
				{
					evaluate = MethodInfoFastRef.ExecutionBuildResultEvaluateMethod.MakeGenericMethod(projectionExpression.Type);
				}
				else
				{
					evaluate = MethodInfoFastRef.ExecutionBuildResultEvaluateMethod.MakeGenericMethod(typeof(IEnumerable<>).MakeGenericType(projectionExpression.Type.GetSequenceElementType()));
				}
				
				return Expression.Call(Expression.Call(Expression.Property(this.objectProjector, "QueryProvider"), method, Expression.Constant(SqlAggregateProjectionNormalizer.Normalize(projectionExpression)), projectionProjector, Expression.NewArrayInit(typeof(object), values), rootKeys), evaluate);
			}
		}