public virtual RawSqlCommand Build(string sql, IReadOnlyList <object> parameters) { Check.NotEmpty(sql, nameof(sql)); Check.NotNull(parameters, nameof(parameters)); var relationalCommandBuilder = _relationalCommandBuilderFactory.Create(); var substitutions = new string[parameters.Count]; var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var parameterValues = new Dictionary <string, object>(); for (var i = 0; i < substitutions.Length; i++) { var parameterName = parameterNameGenerator.GenerateNext(); substitutions[i] = _sqlGenerationHelper.GenerateParameterName(parameterName); relationalCommandBuilder.AddParameter( parameterName, substitutions[i]); parameterValues.Add(parameterName, parameters[i]); } // ReSharper disable once CoVariantArrayConversion sql = string.Format(sql, substitutions); return(new RawSqlCommand( relationalCommandBuilder.Append(sql).Build(), parameterValues)); }
public virtual IRelationalCommand Build(string sql, IReadOnlyList <object> parameters = null) { Check.NotEmpty(sql, nameof(sql)); var relationalCommandBuilder = _relationalCommandBuilderFactory.Create(); if (parameters != null) { var substitutions = new string[parameters.Count]; var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); for (var i = 0; i < substitutions.Length; i++) { var parameterName = parameterNameGenerator.GenerateNext(); substitutions[i] = _sqlGenerationHelper.GenerateParameterName(parameterName); relationalCommandBuilder.AddParameter( substitutions[i], parameters[i], parameterName); } // ReSharper disable once CoVariantArrayConversion sql = string.Format(sql, substitutions); } return(relationalCommandBuilder.Append(sql).Build()); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual IEnumerable <ModificationCommandBatch> BatchCommands(IReadOnlyList <IUpdateEntry> entries) { var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var commands = CreateModificationCommands(entries, parameterNameGenerator.GenerateNext); var sortedCommandSets = TopologicalSort(commands); // TODO: Enable batching of dependent commands by passing through the dependency graph foreach (var independentCommandSet in sortedCommandSets) { independentCommandSet.Sort(_modificationCommandComparer); var batch = _modificationCommandBatchFactory.Create(); foreach (var modificationCommand in independentCommandSet) { if (!batch.AddCommand(modificationCommand)) { yield return(batch); parameterNameGenerator.Reset(); batch = _modificationCommandBatchFactory.Create(); batch.AddCommand(modificationCommand); } } yield return(batch); } }
public (SelectExpression selectExpression, bool canCache) Optimize(SelectExpression selectExpression, IReadOnlyDictionary <string, object> parametersValues) { var canCache = true; var inExpressionOptimized = new InExpressionValuesExpandingExpressionVisitor( _sqlExpressionFactory, parametersValues).Visit(selectExpression); if (!ReferenceEquals(selectExpression, inExpressionOptimized)) { canCache = false; } var nullParametersOptimized = new ParameterNullabilityBasedSqlExpressionOptimizingExpressionVisitor( _sqlExpressionFactory, _useRelationalNulls, parametersValues).Visit(inExpressionOptimized); var fromSqlParameterOptimized = new FromSqlParameterApplyingExpressionVisitor( _sqlExpressionFactory, _parameterNameGeneratorFactory.Create(), parametersValues).Visit(nullParametersOptimized); if (!ReferenceEquals(nullParametersOptimized, fromSqlParameterOptimized)) { canCache = false; } return(selectExpression : (SelectExpression)fromSqlParameterOptimized, canCache); }
public virtual IRelationalCommand Build( [NotNull] string sql, [CanBeNull] IReadOnlyList <object> parameters = null) { Check.NotEmpty(sql, nameof(sql)); var builder = _commandBuilderFactory.Create(); if (parameters != null) { var substitutions = new string[parameters.Count]; var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); for (var index = 0; index < substitutions.Length; index++) { substitutions[index] = _sqlGenerator.GenerateParameterName( parameterNameGenerator.GenerateNext()); builder.AddParameter( substitutions[index], parameters[index]); } sql = string.Format(sql, substitutions); } return(builder.Append(sql).BuildRelationalCommand()); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual RawSqlCommand Build(string sql, IEnumerable <object> parameters) { Check.NotEmpty(sql, nameof(sql)); Check.NotNull(parameters, nameof(parameters)); var relationalCommandBuilder = _relationalCommandBuilderFactory.Create(); var substitutions = new List <string>(); var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var parameterValues = new Dictionary <string, object>(); foreach (var parameter in parameters) { var parameterName = parameterNameGenerator.GenerateNext(); var substitutedName = _sqlGenerationHelper.GenerateParameterName(parameterName); substitutions.Add(substitutedName); relationalCommandBuilder.AddParameter(parameterName, substitutedName); parameterValues.Add(parameterName, parameter); } // ReSharper disable once CoVariantArrayConversion sql = string.Format(sql, substitutions.ToArray()); return(new RawSqlCommand( relationalCommandBuilder.Append(sql).Build(), parameterValues)); }
public SelectExpression Optimize(SelectExpression selectExpression, IReadOnlyDictionary <string, object> parametersValues) { var query = new InExpressionValuesExpandingExpressionVisitor( _sqlExpressionFactory, parametersValues).Visit(selectExpression); query = new FromSqlParameterApplyingExpressionVisitor( _sqlExpressionFactory, _parameterNameGeneratorFactory.Create(), parametersValues).Visit(query); return((SelectExpression)query); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual IEnumerable <ModificationCommandBatch> BatchCommands(IReadOnlyList <IUpdateEntry> entries) { var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var commands = CreateModificationCommands(entries, parameterNameGenerator.GenerateNext); var sortedCommandSets = TopologicalSort(commands); // TODO: Enable batching of dependent commands by passing through the dependency graph foreach (var independentCommandSet in sortedCommandSets) { independentCommandSet.Sort(_modificationCommandComparer); var batch = _modificationCommandBatchFactory.Create(); foreach (var modificationCommand in independentCommandSet) { Validate(modificationCommand); if (!batch.AddCommand(modificationCommand)) { if (batch.ModificationCommands.Count == 1 || batch.ModificationCommands.Count >= _minBatchSize) { yield return(batch); } else { foreach (var command in batch.ModificationCommands) { yield return(StartNewBatch(parameterNameGenerator, command)); } } batch = StartNewBatch(parameterNameGenerator, modificationCommand); } } if (batch.ModificationCommands.Count == 1 || batch.ModificationCommands.Count >= _minBatchSize) { yield return(batch); } else { foreach (var command in batch.ModificationCommands) { yield return(StartNewBatch(parameterNameGenerator, command)); } } } }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual RawSqlCommand Build(string sql, IEnumerable <object> parameters) { var relationalCommandBuilder = _relationalCommandBuilderFactory.Create(); var substitutions = new List <string>(); var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var parameterValues = new Dictionary <string, object?>(); foreach (var parameter in parameters) { if (parameter is DbParameter dbParameter) { if (string.IsNullOrEmpty(dbParameter.ParameterName)) { dbParameter.ParameterName = _sqlGenerationHelper.GenerateParameterName(parameterNameGenerator.GenerateNext()); } substitutions.Add(_sqlGenerationHelper.GenerateParameterName(dbParameter.ParameterName)); relationalCommandBuilder.AddRawParameter(dbParameter.ParameterName, dbParameter); } else { var parameterName = parameterNameGenerator.GenerateNext(); var substitutedName = _sqlGenerationHelper.GenerateParameterName(parameterName); substitutions.Add(substitutedName); var typeMapping = parameter == null ? _typeMappingSource.GetMappingForValue(null) : _typeMappingSource.GetMapping(parameter.GetType()); var nullable = parameter == null || parameter.GetType().IsNullableType(); relationalCommandBuilder.AddParameter(parameterName, substitutedName, typeMapping, nullable); parameterValues.Add(parameterName, parameter); } } // ReSharper disable once CoVariantArrayConversion sql = string.Format(sql, substitutions.ToArray()); return(new RawSqlCommand( relationalCommandBuilder.Append(sql).Build(), parameterValues)); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SelectExpression Expand( [NotNull] SelectExpression selectExpression, [NotNull] IReadOnlyDictionary <string, object> parameterValues, out bool canCache) { Check.NotNull(selectExpression, nameof(selectExpression)); Check.NotNull(parameterValues, nameof(parameterValues)); _visitedFromSqlExpressions.Clear(); _parameterNameGenerator = _parameterNameGeneratorFactory.Create(); _parametersValues = parameterValues; _canCache = true; var result = (SelectExpression)Visit(selectExpression); canCache = _canCache; return(result); }
protected virtual IEnumerable <ModificationCommand> CreateModificationCommands([NotNull] IReadOnlyList <IUpdateEntry> entries) { var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); // TODO: Handle multiple state entries that update the same row return(entries.Select( e => { var command = new ModificationCommand( _annotationProvider.For(e.EntityType).TableName, _annotationProvider.For(e.EntityType).Schema, parameterNameGenerator, _annotationProvider.For); command.AddEntry(e); return command; })); }
private RelationalCommand CreateCommand( string sql, object[] parameters) { var builder = _relationalCommandBuilderFactory.Create(); var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var substitutions = new string[parameters.Length]; for (var index = 0; index < substitutions.Length; index++) { substitutions[index] = parameterNameGenerator.GenerateNext(); builder.AddParameter( substitutions[index], parameters[index]); } builder.AppendLines(string.Format(sql, substitutions)); return(builder.BuildRelationalCommand()); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual IEnumerable <ModificationCommandBatch> BatchCommands(IList <IUpdateEntry> entries) { var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var commands = CreateModificationCommands(entries, parameterNameGenerator.GenerateNext); var sortedCommandSets = TopologicalSort(commands); // TODO: Enable batching of dependent commands by passing through the dependency graph foreach (var independentCommandSet in sortedCommandSets) { independentCommandSet.Sort(_modificationCommandComparer); var batch = _modificationCommandBatchFactory.Create(); foreach (var modificationCommand in independentCommandSet) { if (!batch.AddCommand(modificationCommand)) { if (batch.ModificationCommands.Count == 1 || batch.ModificationCommands.Count >= _minBatchSize) { if (batch.ModificationCommands.Count > 1) { Dependencies.UpdateLogger.BatchReadyForExecution( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count); } yield return(batch); } else { Dependencies.UpdateLogger.BatchSmallerThanMinBatchSize( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count, _minBatchSize); foreach (var command in batch.ModificationCommands) { yield return(StartNewBatch(parameterNameGenerator, command)); } } batch = StartNewBatch(parameterNameGenerator, modificationCommand); } } if (batch.ModificationCommands.Count == 1 || batch.ModificationCommands.Count >= _minBatchSize) { if (batch.ModificationCommands.Count > 1) { Dependencies.UpdateLogger.BatchReadyForExecution( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count); } yield return(batch); } else { Dependencies.UpdateLogger.BatchSmallerThanMinBatchSize( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count, _minBatchSize); foreach (var command in batch.ModificationCommands) { yield return(StartNewBatch(parameterNameGenerator, command)); } } } }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual IEnumerable <ModificationCommandBatch> BatchCommands( IList <IUpdateEntry> entries, IUpdateAdapter updateAdapter) { var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); var commands = CreateModificationCommands(entries, updateAdapter, parameterNameGenerator.GenerateNext); var sortedCommandSets = TopologicalSort(commands); foreach (var independentCommandSet in sortedCommandSets) { independentCommandSet.Sort(_modificationCommandComparer); var batch = _modificationCommandBatchFactory.Create(); foreach (var modificationCommand in independentCommandSet) { modificationCommand.AssertColumnsNotInitialized(); if (modificationCommand.EntityState == EntityState.Modified && !modificationCommand.ColumnModifications.Any(m => m.IsWrite)) { continue; } if (!batch.AddCommand(modificationCommand)) { if (batch.ModificationCommands.Count == 1 || batch.ModificationCommands.Count >= _minBatchSize) { if (batch.ModificationCommands.Count > 1) { Dependencies.UpdateLogger.BatchReadyForExecution( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count); } yield return(batch); } else { Dependencies.UpdateLogger.BatchSmallerThanMinBatchSize( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count, _minBatchSize); foreach (var command in batch.ModificationCommands) { yield return(StartNewBatch(parameterNameGenerator, command)); } } batch = StartNewBatch(parameterNameGenerator, modificationCommand); } } if (batch.ModificationCommands.Count == 1 || batch.ModificationCommands.Count >= _minBatchSize) { if (batch.ModificationCommands.Count > 1) { Dependencies.UpdateLogger.BatchReadyForExecution( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count); } yield return(batch); } else { Dependencies.UpdateLogger.BatchSmallerThanMinBatchSize( batch.ModificationCommands.SelectMany(c => c.Entries), batch.ModificationCommands.Count, _minBatchSize); foreach (var command in batch.ModificationCommands) { yield return(StartNewBatch(parameterNameGenerator, command)); } } } }