Пример #1
0
 public ObjectProjector(SqlQueryProvider queryProvider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryFormatResult formatResult)
 {
     this.QueryProvider      = queryProvider;
     this.DataAccessModel    = dataAccessModel;
     this.SqlDatabaseContext = sqlDatabaseContext;
     this.formatResult       = formatResult;
 }
Пример #2
0
		public ObjectProjector(SqlQueryProvider queryProvider, DataAccessModel dataAccessModel, SqlDatabaseContext sqlDatabaseContext, SqlQueryFormatResult formatResult)
		{
			this.QueryProvider = queryProvider;
			this.DataAccessModel = dataAccessModel;
			this.SqlDatabaseContext = sqlDatabaseContext;
			this.formatResult = formatResult;
		}
Пример #3
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;
 }
Пример #4
0
        internal string GetQueryText(SqlQueryFormatResult formatResult, Func <int, FormatParamValue> paramSelector = null)
        {
            var sql = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(formatResult.CommandText, c =>
            {
                var index = c.IndexOf(char.IsDigit);

                index = int.Parse(c.Substring(index));

                return(paramSelector?.Invoke(index) ?? new FormatParamValue(formatResult.ParameterValues[index].Value, true));
            });

            return(sql);
        }
Пример #5
0
        internal string GetQueryText(SqlQueryFormatResult formatResult)
        {
            var sql = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(formatResult.CommandText, c =>
            {
                var index = c.IndexOf(char.IsDigit);

                if (index < 0)
                {
                    return("(?!)");
                }

                index = int.Parse(c.Substring(index));

                return(formatResult.ParameterValues[index].Value);
            });

            return(sql);
        }
Пример #6
0
        internal string GetQueryText(SqlQueryFormatResult formatResult, Func <int, string> toString = null)
        {
            var formatManager = this.SqlDatabaseContext.SqlQueryFormatterManager;

            var sql = formatManager.SubstitutedParameterValues(formatResult.CommandText, (parameterName, formatConstant) =>
            {
                var index = 0;
                var start = parameterName.IndexOf(char.IsDigit);

                for (var i = start; i < parameterName.Length; i++)
                {
                    index *= 10;
                    index  = parameterName[i] - '0';
                }

                return(toString?.Invoke(index) ?? formatConstant(formatResult.ParameterValues[index].Value));
            });

            return(sql);
        }
 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)
 {
 }
 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;
 }
Пример #9
0
        internal ExecutionBuildResult BuildExecution(Expression expression, LambdaExpression projection = null, object[] placeholderValues = null)
        {
            ProjectorExpressionCacheInfo cacheInfo;
            var skipFormatResultSubstitution = false;
            var projectionExpression         = expression as SqlProjectionExpression ?? (SqlProjectionExpression)Bind(this.DataAccessModel, this.SqlDatabaseContext.SqlDataTypeProvider, expression);

            var key = new ExpressionCacheKey(projectionExpression, projection);

            if (!this.SqlDatabaseContext.projectionExpressionCache.TryGetValue(key, out cacheInfo))
            {
                if (expression != projectionExpression)
                {
                    placeholderValues            = SqlConstantPlaceholderValuesCollector.CollectValues(projectionExpression);
                    projectionExpression         = (SqlProjectionExpression)Optimize(this.DataAccessModel, this.SqlDatabaseContext, projectionExpression);
                    skipFormatResultSubstitution = true;
                }

                var oldCache     = this.SqlDatabaseContext.projectionExpressionCache;
                var formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(projectionExpression);

                SqlQueryFormatResult formatResultForCache = null;

                if (formatResult.Cacheable)
                {
                    var parameters = formatResult.ParameterValues.ToList();

                    foreach (var index in formatResult.ParameterIndexToPlaceholderIndexes.Keys)
                    {
                        var value = parameters[index];

                        parameters[index] = value.ChangeValue(value.Type.GetDefaultValue());
                    }

                    formatResultForCache = formatResult.ChangeParameterValues(parameters);
                }
                else
                {
                    if (!skipFormatResultSubstitution)
                    {
                        // Edge case where inner projection from ProjectionBuilder can't be cached (related DeflatedPredicated with a complex predicate)

                        skipFormatResultSubstitution = true;

                        projectionExpression = (SqlProjectionExpression)SqlConstantPlaceholderReplacer.Replace(projectionExpression, placeholderValues);

                        formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(projectionExpression);
                    }
                }

                cacheInfo = new ProjectorExpressionCacheInfo(projectionExpression, formatResultForCache);

                if (projection == null)
                {
                    var columns = projectionExpression.Select.Columns.Select(c => c.Name);

                    projection = ProjectionBuilder.Build(this.DataAccessModel, this.SqlDatabaseContext, this, projectionExpression.Projector, new ProjectionBuilderScope(columns.ToArray()));
                }

                BuildProjector(projection, projectionExpression.Aggregator, out cacheInfo.projector, out cacheInfo.asyncProjector);

                if (this.SqlDatabaseContext.projectionExpressionCache.Count >= ProjectorCacheMaxLimit)
                {
                    ProjectionExpressionCacheLogger.Debug(() => $"ProjectionExpressionCache has been flushed because it overflowed with a size of {ProjectionExpressionCacheMaxLimit}\n\nProjectionExpression: {projectionExpression}\n\nAt: {new StackTrace()}");

                    var newCache = new Dictionary <ExpressionCacheKey, ProjectorExpressionCacheInfo>(ProjectorCacheMaxLimit, ExpressionCacheKeyEqualityComparer.Default);

                    foreach (var value in oldCache.Take(oldCache.Count / 3))
                    {
                        newCache[value.Key] = value.Value;
                    }

                    newCache[key] = cacheInfo;

                    this.SqlDatabaseContext.projectionExpressionCache = newCache;
                }
                else
                {
                    var newCache = new Dictionary <ExpressionCacheKey, ProjectorExpressionCacheInfo>(oldCache, ExpressionCacheKeyEqualityComparer.Default)
                    {
                        [key] = cacheInfo
                    };

                    this.SqlDatabaseContext.projectionExpressionCache = newCache;
                }

                ProjectionCacheLogger.Debug(() => $"Cached projection for query:\n{GetQueryText(formatResult)}\n\nProjector:\n{cacheInfo.projector}");
                ProjectionCacheLogger.Debug(() => $"Projector Cache Size: {this.SqlDatabaseContext.projectionExpressionCache.Count}");

                cacheInfo.formatResult = formatResult;
            }
            else
            {
                ProjectionCacheLogger.Debug(() => $"Cache hit for query:\n{GetQueryText(cacheInfo.formatResult)}");
            }

            if (placeholderValues == null)
            {
                placeholderValues = SqlConstantPlaceholderValuesCollector.CollectValues(projectionExpression);
            }

            if (cacheInfo.formatResult == null)
            {
                var projector          = SqlConstantPlaceholderReplacer.Replace(cacheInfo.projectionExpression, placeholderValues);
                var optimizedProjector = Optimize(this.DataAccessModel, this.SqlDatabaseContext, projector);

                cacheInfo.formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(optimizedProjector);
            }
            else if (!skipFormatResultSubstitution)
            {
                var parameters = cacheInfo.formatResult.ParameterValues.ToList();

                foreach (var indexes in cacheInfo.formatResult.ParameterIndexToPlaceholderIndexes)
                {
                    var index            = indexes.Key;
                    var placeholderIndex = indexes.Value;

                    parameters[index] = parameters[index].ChangeValue(placeholderValues[placeholderIndex]);
                }

                cacheInfo.formatResult = cacheInfo.formatResult.ChangeParameterValues(parameters);
            }

            return(new ExecutionBuildResult(this, cacheInfo.formatResult, cacheInfo.projector, cacheInfo.asyncProjector, placeholderValues));
        }
Пример #10
0
 public ObjectProjector(IQueryProvider provider, DataAccessModel dataAccessModel, SqlQueryFormatResult formatResult, SqlDatabaseContext sqlDatabaseContext, IRelatedDataAccessObjectContext relatedDataAccessObjectContext, SelectFirstType selectFirstType, SqlAggregateType?sqlAggregateType, bool isDefaultIfEmpty)
 {
     this.sqlAggregateType               = sqlAggregateType;
     this.isDefaultIfEmpty               = isDefaultIfEmpty;
     this.provider                       = provider;
     this.DataAccessModel                = dataAccessModel;
     this.FormatResult                   = formatResult;
     this.SqlDatabaseContext             = sqlDatabaseContext;
     this.selectFirstType                = selectFirstType;
     this.relatedDataAccessObjectContext = relatedDataAccessObjectContext;
 }
Пример #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>();
 }
Пример #12
0
 public DataAccessObjectProjector(IQueryProvider provider, DataAccessModel dataAccessModel, SqlQueryFormatResult formatResult, SqlDatabaseContext sqlDatabaseContext, Delegate objectReader, IRelatedDataAccessObjectContext relatedDataAccessObjectContext, SelectFirstType selectFirstType, SqlAggregateType?sqlAggregateType, bool isDefaultIfEmpty, object[] placeholderValues)
     : base(provider, dataAccessModel, formatResult, sqlDatabaseContext, objectReader, relatedDataAccessObjectContext, selectFirstType, sqlAggregateType, isDefaultIfEmpty, placeholderValues)
 {
 }
Пример #13
0
        internal ExecutionBuildResult BuildExecution(Expression expression, LambdaExpression projection = null, object[] placeholderValues = null, Expression <Func <IDataReader, object[]> > rootKeys = null)
        {
            var skipFormatResultSubstitution = false;
            var projectionExpression         = expression as SqlProjectionExpression ?? (SqlProjectionExpression)Bind(this.DataAccessModel, this.SqlDatabaseContext.SqlDataTypeProvider, expression);

            var foundCachedProjection = false;
            var key = new ExpressionCacheKey(projectionExpression, projection);

            if (!this.SqlDatabaseContext.projectionExpressionCache.TryGetValue(key, out var cacheInfo))
            {
                if (expression != projectionExpression)
                {
                    placeholderValues            = SqlConstantPlaceholderValuesCollector.CollectValues(projectionExpression);
                    projectionExpression         = (SqlProjectionExpression)Optimize(this.DataAccessModel, projectionExpression);
                    skipFormatResultSubstitution = true;
                }

                var formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(projectionExpression, SqlQueryFormatterOptions.Default);

                SqlQueryFormatResult formatResultForCache = null;

                if (formatResult.Cacheable)
                {
                    var parameters = formatResult.ParameterValues.ToList();

                    foreach (var index in formatResult.ParameterIndexToPlaceholderIndexes.Keys)
                    {
                        var value = parameters[index];

                        parameters[index] = value.ChangeValue(value.Type.GetDefaultValue());
                    }

                    formatResultForCache = formatResult.ChangeParameterValues(parameters);
                }
                else
                {
                    if (!skipFormatResultSubstitution)
                    {
                        // Edge case where inner projection from ProjectionBuilder can't be cached (related DeflatedPredicated with a complex predicate)

                        skipFormatResultSubstitution = true;

                        projectionExpression = (SqlProjectionExpression)SqlConstantPlaceholderReplacer.Replace(projectionExpression, placeholderValues);

                        formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(projectionExpression);
                    }
                }

                cacheInfo = new ProjectorExpressionCacheInfo(projectionExpression, formatResultForCache);

                var columns = projectionExpression.Select.Columns.Select(c => c.Name).ToArray();

                if (projection == null)
                {
                    projection = ProjectionBuilder.Build(this.DataAccessModel, this.SqlDatabaseContext, this, projectionExpression.Projector, new ProjectionBuilderScope(columns), out rootKeys);
                }

                this.BuildProjector(projection, projectionExpression.Aggregator, rootKeys, out cacheInfo.projector, out cacheInfo.asyncProjector);

                this.SqlDatabaseContext.projectionExpressionCache = this.SqlDatabaseContext.projectionExpressionCache.Clone(key, cacheInfo, "ProjectionExpression", this.ProjectionExpressionCacheMaxLimit, ProjectionCacheLogger, c => c.projectionExpression.ToString());

                ProjectionCacheLogger.Debug(() => $"Cached projection for query:\n{this.GetQueryText(formatResult, this.GetParamName)}\n\nProjector:\n{cacheInfo.projector}");
                ProjectionCacheLogger.Debug(() => $"Projector Cache Size: {this.SqlDatabaseContext.projectionExpressionCache.Count}");

                cacheInfo.formatResult = formatResult;
            }
            else
            {
                foundCachedProjection = true;
            }

            if (placeholderValues == null)
            {
                placeholderValues = SqlConstantPlaceholderValuesCollector.CollectValues(projectionExpression);
            }

            if (cacheInfo.formatResult == null)
            {
                var projector          = SqlConstantPlaceholderReplacer.Replace(cacheInfo.projectionExpression, placeholderValues);
                var optimizedProjector = Optimize(this.DataAccessModel, projector);

                cacheInfo.formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(optimizedProjector);
            }
            else if (!skipFormatResultSubstitution)
            {
                var parameters = cacheInfo.formatResult.ParameterValues.ToList();

                foreach (var indexes in cacheInfo.formatResult.ParameterIndexToPlaceholderIndexes)
                {
                    var index            = indexes.Key;
                    var placeholderIndex = indexes.Value;

                    parameters[index] = parameters[index].ChangeValue(placeholderValues[placeholderIndex]);
                }

                cacheInfo.formatResult = cacheInfo.formatResult.ChangeParameterValues(parameters);
            }

            if (foundCachedProjection)
            {
                ProjectionCacheLogger.Debug(() => $"Cache hit for query:\n{this.GetQueryText(cacheInfo.formatResult, this.GetParamName)}");
            }

            return(new ExecutionBuildResult(this, cacheInfo.formatResult, cacheInfo.projector, cacheInfo.asyncProjector, placeholderValues));
        }
Пример #14
0
		public ProjectorExpressionCacheInfo(SqlProjectionExpression projectionExpression, SqlQueryFormatResult formatResult)
			: this()
		{
			this.projectionExpression = projectionExpression;
			this.formatResult = formatResult;
		}
Пример #15
0
 public ProjectorExpressionCacheInfo(SqlProjectionExpression projectionExpression, SqlQueryFormatResult formatResult)
     : this()
 {
     this.projectionExpression = projectionExpression;
     this.formatResult         = formatResult;
 }