public virtual void Detects_duplicate_foreignKey_names_within_hierarchy_with_different_column_order() { var modelBuilder = CreateConventionalModelBuilder(); modelBuilder.Entity <Animal>(); modelBuilder.Entity <Cat>( et => { et.Property(c => c.Breed).HasColumnName("Breed"); et.HasOne <Person>().WithMany() .HasForeignKey( c => new { c.Name, c.Breed }) .HasPrincipalKey( p => new { p.Name, p.FavoriteBreed }) .HasConstraintName("FK"); }); modelBuilder.Entity <Dog>( et => { et.Property(c => c.Breed).HasColumnName("Breed"); et.HasOne <Person>().WithMany() .HasForeignKey( d => new { d.Breed, d.Name }) .HasPrincipalKey( p => new { p.FavoriteBreed, p.Name }) .HasConstraintName("FK"); }); VerifyError( RelationalStrings.DuplicateForeignKeyColumnMismatch( "{'" + nameof(Dog.Breed) + "', '" + nameof(Dog.Name) + "'}", nameof(Dog), "{'" + nameof(Cat.Name) + "', '" + nameof(Cat.Breed) + "'}", nameof(Cat), nameof(Animal), "FK", "{'" + nameof(Dog.Breed) + "', '" + nameof(Dog.Name) + "'}", "{'" + nameof(Cat.Name) + "', '" + nameof(Cat.Breed) + "'}"), modelBuilder.Model); }
private void ValidateState(IUpdateEntry mainEntry, IUpdateEntry entry) { var mainEntryState = mainEntry.SharedIdentityEntry == null ? mainEntry.EntityState : EntityState.Modified; if (mainEntryState == EntityState.Modified) { return; } var entryState = entry.SharedIdentityEntry == null ? entry.EntityState : EntityState.Modified; if (mainEntryState != entryState) { if (_sensitiveLoggingEnabled) { throw new InvalidOperationException( RelationalStrings.ConflictingRowUpdateTypesSensitive( entry.EntityType.DisplayName(), entry.BuildCurrentValuesString(entry.EntityType.FindPrimaryKey().Properties), entryState, mainEntry.EntityType.DisplayName(), mainEntry.BuildCurrentValuesString(mainEntry.EntityType.FindPrimaryKey().Properties), mainEntryState)); } throw new InvalidOperationException( RelationalStrings.ConflictingRowUpdateTypes( entry.EntityType.DisplayName(), entryState, mainEntry.EntityType.DisplayName(), mainEntryState)); } }
protected virtual bool CanSetDefaultValue([CanBeNull] object value) { if (GetDefaultValue(false) == value) { return(true); } if (!Annotations.CanSetAnnotation( RelationalFullAnnotationNames.Instance.DefaultValue, ProviderFullAnnotationNames?.DefaultValue, value)) { return(false); } if (ShouldThrowOnConflict) { if (GetDefaultValueSql(false) != null) { throw new InvalidOperationException( RelationalStrings.ConflictingColumnServerGeneration(nameof(DefaultValue), Property.Name, nameof(DefaultValueSql))); } if (GetComputedColumnSql(false) != null) { throw new InvalidOperationException( RelationalStrings.ConflictingColumnServerGeneration(nameof(DefaultValue), Property.Name, nameof(ComputedColumnSql))); } } else if (value != null && (!CanSetDefaultValueSql(null) || !CanSetComputedColumnSql(null))) { return(false); } return(true); }
private DbCommand CreateCommand( IRelationalConnection connection, IReadOnlyDictionary <string, object> parameterValues) { var command = connection.DbConnection.CreateCommand(); ((OracleCommand)command).BindByName = true; command.CommandText = CommandText; if (connection.CurrentTransaction != null) { command.Transaction = connection.CurrentTransaction.GetDbTransaction(); } if (connection.CommandTimeout != null) { command.CommandTimeout = (int)connection.CommandTimeout; } if (Parameters.Count > 0) { if (parameterValues == null) { throw new InvalidOperationException( RelationalStrings.MissingParameterValue( Parameters[0].InvariantName)); } foreach (var parameter in Parameters) { parameter.AddDbParameter(command, parameterValues); } } return(command); }
public virtual void Detects_duplicate_index_names_within_hierarchy_with_different_column_order() { var modelBuilder = CreateConventionalModelBuilder(); modelBuilder.Entity <Animal>(); modelBuilder.Entity <Cat>( et => { et.Property(c => c.Breed).HasColumnName("Breed"); et.HasIndex( c => new { c.Name, c.Breed }).HasName("IX"); }); modelBuilder.Entity <Dog>( et => { et.Property(c => c.Breed).HasColumnName("Breed"); et.HasIndex( d => new { d.Breed, d.Name }).HasName("IX"); }); VerifyError( RelationalStrings.DuplicateIndexColumnMismatch( "{'" + nameof(Dog.Breed) + "', '" + nameof(Dog.Name) + "'}", nameof(Dog), "{'" + nameof(Cat.Name) + "', '" + nameof(Cat.Breed) + "'}", nameof(Cat), nameof(Animal), "IX", "{'" + nameof(Dog.Breed) + "', '" + nameof(Dog.Name) + "'}", "{'" + nameof(Cat.Name) + "', '" + nameof(Cat.Breed) + "'}"), modelBuilder.Model); }
/// <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> protected virtual DbCommand CreateCommand( IRelationalConnection connection, IReadOnlyDictionary <string, object> parameterValues) { var command = connection.DbConnection.CreateCommand(); command.CommandText = AdjustCommandText(CommandText); ConfigureCommand(command); if (connection.CurrentTransaction != null) { command.Transaction = connection.CurrentTransaction.GetDbTransaction(); } if (connection.CommandTimeout != null) { command.CommandTimeout = (int)connection.CommandTimeout; } if (Parameters.Count > 0) { if (parameterValues == null) { throw new InvalidOperationException( RelationalStrings.MissingParameterValue( Parameters[0].InvariantName)); } foreach (var parameter in Parameters) { parameter.AddDbParameter(command, parameterValues); } } return(command); }
public virtual EntityProjectionExpression UpdateEntityType([NotNull] IEntityType derivedType) { Check.NotNull(derivedType, nameof(derivedType)); if (!derivedType.GetAllBaseTypes().Contains(EntityType)) { throw new InvalidOperationException( RelationalStrings.InvalidDerivedTypeInEntityProjection( derivedType.DisplayName(), EntityType.DisplayName())); } var propertyExpressionMap = new Dictionary <IProperty, ColumnExpression>(); foreach (var kvp in _propertyExpressionMap) { var property = kvp.Key; if (derivedType.IsAssignableFrom(property.DeclaringEntityType) || property.DeclaringEntityType.IsAssignableFrom(derivedType)) { propertyExpressionMap[property] = kvp.Value; } } var discriminatorExpression = DiscriminatorExpression; if (DiscriminatorExpression is CaseExpression caseExpression) { var entityTypesToSelect = derivedType.GetTptDiscriminatorValues(); var whenClauses = caseExpression.WhenClauses .Where(wc => entityTypesToSelect.Contains((string)((SqlConstantExpression)wc.Result).Value !)) .ToList(); discriminatorExpression = caseExpression.Update(operand: null, whenClauses, elseResult: null); } return(new EntityProjectionExpression(derivedType, propertyExpressionMap, discriminatorExpression)); }
public void Inserts_are_batched_only_when_necessary(int minBatchSize) { var expectedBlogs = new List <Blog>(); TestHelpers.ExecuteWithStrategyInTransaction( () => (BloggingContext)Fixture.CreateContext(minBatchSize), UseTransaction, context => { var owner = new Owner(); context.Owners.Add(owner); for (var i = 1; i < 4; i++) { var blog = new Blog { Id = Guid.NewGuid(), Owner = owner }; context.Set <Blog>().Add(blog); expectedBlogs.Add(blog); } Fixture.TestSqlLoggerFactory.Clear(); context.SaveChanges(); Assert.Contains( minBatchSize == 3 ? RelationalStrings.LogBatchReadyForExecution(new TestLogger <SqlServerLoggingDefinitions>()).GenerateMessage(3) : RelationalStrings.LogBatchSmallerThanMinBatchSize(new TestLogger <SqlServerLoggingDefinitions>()).GenerateMessage(3, 4), Fixture.TestSqlLoggerFactory.Log.Select(l => l.Message)); Assert.Equal(minBatchSize <= 3 ? 2 : 4, Fixture.TestSqlLoggerFactory.SqlStatements.Count); }, context => AssertDatabaseState(context, false, expectedBlogs)); }
/// <summary> /// Asynchronously opens the connection to the database. /// </summary> /// <param name="cancellationToken"> /// A <see cref="CancellationToken" /> to observe while waiting for the task to complete. /// </param> /// <returns> A task that represents the asynchronous operation. </returns> public virtual async Task OpenAsync(CancellationToken cancellationToken = default(CancellationToken)) { CheckForAmbientTransactions(); if (_connection.Value.State == ConnectionState.Broken) { _connection.Value.Close(); } if (_connection.Value.State != ConnectionState.Open) { _logger.LogDebug( RelationalEventId.OpeningConnection, new { _connection.Value.Database, _connection.Value.DataSource }, state => RelationalStrings.RelationalLoggerOpeningConnection( state.Database, state.DataSource)); await _connection.Value.OpenAsync(cancellationToken); if (_openedCount == 0) { _openedInternally = true; _openedCount++; } } else { _openedCount++; } }
public async Task Throws_when_parameters_are_configured_and_value_is_missing( Delegate commandDelegate, string telemetryName, bool async) { var fakeConnection = CreateConnection(); var relationalCommand = CreateRelationalCommand( parameters: new[] { new TypeMappedRelationalParameter("FirstInvariant", "FirstParameter", new RelationalTypeMapping("int", typeof(int), DbType.Int32), false), new TypeMappedRelationalParameter("SecondInvariant", "SecondParameter", new RelationalTypeMapping("long", typeof(long), DbType.Int64), true), new TypeMappedRelationalParameter("ThirdInvariant", "ThirdParameter", RelationalTypeMapping.NullMapping, null) }); var parameterValues = new Dictionary <string, object> { { "FirstInvariant", 17 }, { "SecondInvariant", 18L } }; if (async) { Assert.Equal( RelationalStrings.MissingParameterValue("ThirdInvariant"), (await Assert.ThrowsAsync <InvalidOperationException>(async() => await((CommandFunc)commandDelegate)(fakeConnection, relationalCommand, parameterValues))).Message); } else { Assert.Equal( RelationalStrings.MissingParameterValue("ThirdInvariant"), Assert.Throws <InvalidOperationException>(() => ((CommandAction)commandDelegate)(fakeConnection, relationalCommand, parameterValues)).Message); } }
public virtual void AddEntry([NotNull] IUpdateEntry entry) { Check.NotNull(entry, nameof(entry)); if ((entry.EntityState != EntityState.Added) && (entry.EntityState != EntityState.Modified) && (entry.EntityState != EntityState.Deleted)) { throw new ArgumentException(RelationalStrings.ModificationFunctionInvalidEntityState(entry.EntityState)); } var firstEntry = _entries.FirstOrDefault(); if ((firstEntry != null) && (firstEntry.EntityState != entry.EntityState)) { throw new InvalidOperationException(RelationalStrings.ConflictingRowUpdates); // TODO: Check for any other conflicts between the two entries } _entries.Add(entry); _columnModifications = null; }
/// <summary> /// Validates the mapping/configuration of functions in the model. /// </summary> /// <param name="model"> The model to validate. </param> /// <param name="logger"> The logger to use. </param> protected virtual void ValidateDbFunctions([NotNull] IModel model, [NotNull] IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger) { foreach (var dbFunction in model.GetDbFunctions()) { var methodInfo = dbFunction.MethodInfo; if (string.IsNullOrEmpty(dbFunction.FunctionName)) { throw new InvalidOperationException( RelationalStrings.DbFunctionNameEmpty(methodInfo.DisplayName())); } if (dbFunction.Translation == null) { if (RelationalDependencies.TypeMappingSource.FindMapping(methodInfo.ReturnType) == null) { throw new InvalidOperationException( RelationalStrings.DbFunctionInvalidReturnType( methodInfo.DisplayName(), methodInfo.ReturnType.ShortDisplayName())); } foreach (var parameter in methodInfo.GetParameters()) { if (RelationalDependencies.TypeMappingSource.FindMapping(parameter.ParameterType) == null) { throw new InvalidOperationException( RelationalStrings.DbFunctionInvalidParameterType( parameter.Name, methodInfo.DisplayName(), parameter.ParameterType.ShortDisplayName())); } } } } }
public void DbFunction_Queryable_custom_translation() { var modelBuilder = GetModelBuilder(); var methodInfo = typeof(TestMethods).GetMethod(nameof(TestMethods.MethodJ)); var dbFunctionBuilder = modelBuilder.HasDbFunction(methodInfo); Assert.False(dbFunctionBuilder.GetInfrastructure() .CanSetTranslation(args => new SqlFragmentExpression("Empty"), fromDataAnnotation: true)); Assert.Null(dbFunctionBuilder.Metadata.Translation); dbFunctionBuilder.GetInfrastructure().HasTranslation(args => new SqlFragmentExpression("Empty")); Assert.Null(dbFunctionBuilder.Metadata.Translation); dbFunctionBuilder.GetInfrastructure() .HasTranslation(args => new SqlFragmentExpression("Empty"), fromDataAnnotation: true); Assert.Null(dbFunctionBuilder.Metadata.Translation); Assert.Equal(RelationalStrings.DbFunctionQueryableCustomTranslation(methodInfo.DisplayName()), Assert.Throws <InvalidOperationException>( () => dbFunctionBuilder.HasTranslation(args => new SqlFragmentExpression("Empty"))).Message); var dbFunction = dbFunctionBuilder.Metadata; Assert.Equal(RelationalStrings.DbFunctionQueryableCustomTranslation(methodInfo.DisplayName()), Assert.Throws <InvalidOperationException>( () => ((IConventionDbFunction)dbFunction).SetTranslation(args => new SqlFragmentExpression("Empty"))).Message); Assert.Equal(RelationalStrings.DbFunctionQueryableCustomTranslation(methodInfo.DisplayName()), Assert.Throws <InvalidOperationException>( () => ((IConventionDbFunction)dbFunction) .SetTranslation(args => new SqlFragmentExpression("Empty"), fromDataAnnotation: true)).Message); Assert.Equal(RelationalStrings.DbFunctionQueryableCustomTranslation(methodInfo.DisplayName()), Assert.Throws <InvalidOperationException>( () => dbFunction.Translation = args => new SqlFragmentExpression("Empty")).Message); }
public virtual void Detects_duplicate_foreignKey_names_within_hierarchy_with_different_uniqueness() { var modelBuilder = CreateConventionalModelBuilder(); modelBuilder.Entity <Animal>(); var fk1 = modelBuilder.Entity <Cat>().HasOne <Person>().WithMany().HasForeignKey(c => c.Name).HasPrincipalKey(p => p.Name) .HasConstraintName("FK_Animal_Person_Name").Metadata; var fk2 = modelBuilder.Entity <Dog>().HasOne <Person>().WithOne().HasForeignKey <Dog>(d => d.Name) .HasPrincipalKey <Person>(p => p.Name) .HasConstraintName("FK_Animal_Person_Name").Metadata; VerifyError( RelationalStrings.DuplicateForeignKeyUniquenessMismatch( "{'" + nameof(Dog.Name) + "'}", nameof(Dog), "{'" + nameof(Cat.Name) + "'}", nameof(Cat), nameof(Animal), "FK_Animal_Person_Name"), modelBuilder.Model); var index1 = fk1.DeclaringEntityType.GetDeclaredIndexes().Single(); var index2 = fk2.DeclaringEntityType.GetDeclaredIndexes().Single(); Assert.NotSame(index1, index2); Assert.NotEqual(index1.GetName(), index2.GetName()); }
/// <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 override void AddDbParameter(DbCommand command, object value) { Check.NotNull(command, nameof(command)); Check.NotNull(value, nameof(value)); if (value is object[] innerValues) { if (innerValues.Length < RelationalParameters.Count) { throw new InvalidOperationException( RelationalStrings.MissingParameterValue( RelationalParameters[innerValues.Length].InvariantName)); } for (var i = 0; i < RelationalParameters.Count; i++) { RelationalParameters[i].AddDbParameter(command, innerValues[i]); } } else { throw new InvalidOperationException(RelationalStrings.ParameterNotObjectArray(InvariantName)); } }
public void BatchCommands_throws_on_incomplete_updates_for_shared_table_no_middle_dependent(EntityState state, bool sensitiveLogging) { var currentDbContext = CreateContextServices(CreateSharedTableModel()).GetRequiredService <ICurrentDbContext>(); var stateManager = currentDbContext.GetDependencies().StateManager; var first = new FakeEntity { Id = 42 }; var firstEntry = stateManager.GetOrCreateEntry(first); firstEntry.SetEntityState(state); var second = new AnotherFakeEntity { Id = 42 }; var secondEntry = stateManager.GetOrCreateEntry(second); secondEntry.SetEntityState(state); if (sensitiveLogging) { Assert.Equal(RelationalStrings.SharedRowEntryCountMismatchSensitive( nameof(FakeEntity), nameof(FakeEntity), nameof(DerivedRelatedFakeEntity), "Id:42", state), Assert.Throws <InvalidOperationException>( () => CreateCommandBatchPreparer(currentDbContext: currentDbContext, sensitiveLogging: sensitiveLogging) .BatchCommands(new[] { firstEntry, secondEntry }).ToArray()).Message); } else { Assert.Equal(RelationalStrings.SharedRowEntryCountMismatch( nameof(FakeEntity), nameof(FakeEntity), nameof(DerivedRelatedFakeEntity), state), Assert.Throws <InvalidOperationException>( () => CreateCommandBatchPreparer(currentDbContext: currentDbContext, sensitiveLogging: sensitiveLogging) .BatchCommands(new[] { firstEntry, secondEntry }).ToArray()).Message); } }
public virtual async Task Complex_query_with_groupBy_in_subquery4(bool async) { var message = (await Assert.ThrowsAsync <InvalidOperationException>( () => AssertQuery( async, ss => ss.Set <Customer>() .Select( c => new { Key = c.CustomerID, Subquery = c.Orders .Select(o => new { First = o.OrderID, Second = o.Customer.City + o.CustomerID }) .GroupBy(x => x.Second) .Select(g => new { Sum = g.Sum(x => x.First), Count = g.Count(x => x.Second.StartsWith("Lon")) }).ToList() }), elementSorter: e => e.Key, elementAsserter: (e, a) => { Assert.Equal(e.Key, a.Key); AssertCollection(e.Subquery, a.Subquery); }))).Message; Assert.Equal(RelationalStrings.MissingIdentifyingProjectionInDistinctGroupBySubquery("o.OrderID"), message); }
/// <summary> /// Closes the connection to the database. /// </summary> public virtual void Close() { if (_openedCount > 0 && --_openedCount == 0 && _openedInternally) { if (_connection.Value.State != ConnectionState.Closed) { _logger.LogDebug( RelationalEventId.ClosingConnection, new { _connection.Value.Database, _connection.Value.DataSource }, state => RelationalStrings.RelationalLoggerClosingConnection( state.Database, state.DataSource)); _connection.Value.Close(); } _openedInternally = false; } }
public async Task Exception_thrown_if_rows_returned_for_command_without_store_generated_values_is_not_1() { var entry = CreateEntry(EntityState.Added); var command = new ModificationCommand("T1", null, new ParameterNameGenerator().GenerateNext, true, null); command.AddEntry(entry); var connection = CreateConnection( CreateFakeDataReader( new[] { "Col1" }, new List <object[]> { new object[] { 42 } })); var batch = new ModificationCommandBatchFake(); batch.AddCommand(command); Assert.Equal( RelationalStrings.UpdateConcurrencyException(1, 42), (await Assert.ThrowsAsync <DbUpdateConcurrencyException>( async() => await batch.ExecuteAsync(connection))).Message); }
/// <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 string ResolveConnectionString(string connectionString) { var connectionName = TryGetConnectionName(connectionString); if (connectionName == null) { return(connectionString); } var configuration = _options.FindExtension <CoreOptionsExtension>() ?.ApplicationServiceProvider ?.GetService <IConfiguration>(); var resolved = configuration?[connectionName] ?? configuration?[DefaultSection + connectionName]; if (resolved == null) { throw new InvalidOperationException( RelationalStrings.NamedConnectionStringNotFound(connectionName)); } return(resolved); }
/// <summary> /// Opens the connection to the database. /// </summary> public virtual void Open() { CheckForAmbientTransactions(); if (_connection.Value.State == ConnectionState.Broken) { _connection.Value.Close(); } if (_connection.Value.State != ConnectionState.Open) { _logger.LogDebug( RelationalEventId.OpeningConnection, new { _connection.Value.Database, _connection.Value.DataSource }, state => RelationalStrings.RelationalLoggerOpeningConnection( state.Database, state.DataSource)); _connection.Value.Open(); if (_openedCount == 0) { _openedInternally = true; _openedCount++; } } else { _openedCount++; } }
/// <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> protected virtual void ValidateDbFunctions([NotNull] IModel model) { foreach (var dbFunction in model.Relational().DbFunctions) { var methodInfo = dbFunction.MethodInfo; if (string.IsNullOrEmpty(dbFunction.FunctionName)) { throw new InvalidOperationException( RelationalStrings.DbFunctionNameEmpty(methodInfo.DisplayName())); } if (dbFunction.Translation == null) { if (!RelationalDependencies.TypeMapper.IsTypeMapped(methodInfo.ReturnType)) { throw new InvalidOperationException( RelationalStrings.DbFunctionInvalidReturnType( methodInfo.DisplayName(), methodInfo.ReturnType.ShortDisplayName())); } foreach (var parameter in methodInfo.GetParameters()) { if (!RelationalDependencies.TypeMapper.IsTypeMapped(parameter.ParameterType)) { throw new InvalidOperationException( RelationalStrings.DbFunctionInvalidParameterType( parameter.Name, methodInfo.DisplayName(), parameter.ParameterType.ShortDisplayName())); } } } } }
/// <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 string GenerateScript( string fromMigration = null, string toMigration = null, bool idempotent = false) { IEnumerable <string> appliedMigrations; if (string.IsNullOrEmpty(fromMigration) || fromMigration == Migration.InitialDatabase) { appliedMigrations = Enumerable.Empty <string>(); } else { var fromMigrationId = _migrationsAssembly.GetMigrationId(fromMigration); appliedMigrations = _migrationsAssembly.Migrations .Where(t => string.Compare(t.Key, fromMigrationId, StringComparison.OrdinalIgnoreCase) <= 0) .Select(t => t.Key); } IReadOnlyList <Migration> migrationsToApply, migrationsToRevert; PopulateMigrations( appliedMigrations, toMigration, out migrationsToApply, out migrationsToRevert); var builder = new IndentedStringBuilder(); if (fromMigration == Migration.InitialDatabase || string.IsNullOrEmpty(fromMigration)) { builder.AppendLine(_historyRepository.GetCreateIfNotExistsScript()); builder.Append(_sqlGenerationHelper.BatchTerminator); } for (var i = 0; i < migrationsToRevert.Count; i++) { var migration = migrationsToRevert[i]; var previousMigration = i != migrationsToRevert.Count - 1 ? migrationsToRevert[i + 1] : null; _logger.LogDebug( RelationalEventId.GeneratingMigrationDownScript, () => RelationalStrings.GeneratingDown(migration.GetId())); foreach (var command in GenerateDownSql(migration, previousMigration)) { if (idempotent) { builder.AppendLine(_historyRepository.GetBeginIfExistsScript(migration.GetId())); using (builder.Indent()) { builder.AppendLines(command.CommandText); } builder.AppendLine(_historyRepository.GetEndIfScript()); } else { builder.AppendLine(command.CommandText); } builder.Append(_sqlGenerationHelper.BatchTerminator); } } foreach (var migration in migrationsToApply) { _logger.LogDebug( RelationalEventId.GeneratingMigrationUpScript, () => RelationalStrings.GeneratingUp(migration.GetId())); foreach (var command in GenerateUpSql(migration)) { if (idempotent) { builder.AppendLine(_historyRepository.GetBeginIfNotExistsScript(migration.GetId())); using (builder.Indent()) { builder.AppendLines(command.CommandText); } builder.AppendLine(_historyRepository.GetEndIfScript()); } else { builder.AppendLine(command.CommandText); } builder.Append(_sqlGenerationHelper.BatchTerminator); } } return(builder.ToString()); }
/// <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> protected virtual void ValidateSharedColumnsCompatibility( [NotNull] IReadOnlyList <IEntityType> mappedTypes, [NotNull] string tableName) { var propertyMappings = new Dictionary <string, IProperty>(); foreach (var property in mappedTypes.SelectMany(et => et.GetDeclaredProperties())) { var propertyAnnotations = property.Relational(); var columnName = propertyAnnotations.ColumnName; if (propertyMappings.TryGetValue(columnName, out var duplicateProperty)) { var previousAnnotations = duplicateProperty.Relational(); var currentTypeString = propertyAnnotations.ColumnType ?? TypeMapper.GetMapping(property).StoreType; var previousTypeString = previousAnnotations.ColumnType ?? TypeMapper.GetMapping(duplicateProperty).StoreType; if (!currentTypeString.Equals(previousTypeString, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException( RelationalStrings.DuplicateColumnNameDataTypeMismatch( duplicateProperty.DeclaringEntityType.DisplayName(), duplicateProperty.Name, property.DeclaringEntityType.DisplayName(), property.Name, columnName, tableName, previousTypeString, currentTypeString)); } if (property.IsColumnNullable() != duplicateProperty.IsColumnNullable()) { throw new InvalidOperationException( RelationalStrings.DuplicateColumnNameNullabilityMismatch( duplicateProperty.DeclaringEntityType.DisplayName(), duplicateProperty.Name, property.DeclaringEntityType.DisplayName(), property.Name, columnName, tableName)); } var currentComputedColumnSql = propertyAnnotations.ComputedColumnSql ?? ""; var previousComputedColumnSql = previousAnnotations.ComputedColumnSql ?? ""; if (!currentComputedColumnSql.Equals(previousComputedColumnSql, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException( RelationalStrings.DuplicateColumnNameComputedSqlMismatch( duplicateProperty.DeclaringEntityType.DisplayName(), duplicateProperty.Name, property.DeclaringEntityType.DisplayName(), property.Name, columnName, tableName, previousComputedColumnSql, currentComputedColumnSql)); } var currentDefaultValue = propertyAnnotations.DefaultValue; var previousDefaultValue = previousAnnotations.DefaultValue; if (!Equals(currentDefaultValue, previousDefaultValue)) { throw new InvalidOperationException( RelationalStrings.DuplicateColumnNameDefaultSqlMismatch( duplicateProperty.DeclaringEntityType.DisplayName(), duplicateProperty.Name, property.DeclaringEntityType.DisplayName(), property.Name, columnName, tableName, previousDefaultValue ?? "NULL", currentDefaultValue ?? "NULL")); } var currentDefaultValueSql = propertyAnnotations.DefaultValueSql ?? ""; var previousDefaultValueSql = previousAnnotations.DefaultValueSql ?? ""; if (!currentDefaultValueSql.Equals(previousDefaultValueSql, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException( RelationalStrings.DuplicateColumnNameDefaultSqlMismatch( duplicateProperty.DeclaringEntityType.DisplayName(), duplicateProperty.Name, property.DeclaringEntityType.DisplayName(), property.Name, columnName, tableName, previousDefaultValueSql, currentDefaultValueSql)); } } else { propertyMappings[columnName] = property; } } }
/// <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> protected virtual void ValidateSharedForeignKeysCompatibility( [NotNull] IReadOnlyList <IEntityType> mappedTypes, [NotNull] string tableName) { var foreignKeyMappings = new Dictionary <string, IForeignKey>(); foreach (var foreignKey in mappedTypes.SelectMany(et => et.GetDeclaredForeignKeys())) { var foreignKeyAnnotations = foreignKey.Relational(); var foreignKeyName = foreignKeyAnnotations.Name; if (!foreignKeyMappings.TryGetValue(foreignKeyName, out var duplicateForeignKey)) { foreignKeyMappings[foreignKeyName] = foreignKey; continue; } var principalAnnotations = foreignKey.PrincipalEntityType.Relational(); var principalTable = Format(principalAnnotations.Schema, principalAnnotations.TableName); var duplicateAnnotations = duplicateForeignKey.PrincipalEntityType.Relational(); var duplicatePrincipalTable = Format(duplicateAnnotations.Schema, duplicateAnnotations.TableName); if (!string.Equals(principalTable, duplicatePrincipalTable, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException( RelationalStrings.DuplicateForeignKeyPrincipalTableMismatch( Property.Format(foreignKey.Properties), foreignKey.DeclaringEntityType.DisplayName(), Property.Format(duplicateForeignKey.Properties), duplicateForeignKey.DeclaringEntityType.DisplayName(), tableName, foreignKeyName, principalTable, duplicatePrincipalTable)); } if (!foreignKey.Properties.Select(p => p.Relational().ColumnName) .SequenceEqual(duplicateForeignKey.Properties.Select(p => p.Relational().ColumnName))) { throw new InvalidOperationException( RelationalStrings.DuplicateForeignKeyColumnMismatch( Property.Format(foreignKey.Properties), foreignKey.DeclaringEntityType.DisplayName(), Property.Format(duplicateForeignKey.Properties), duplicateForeignKey.DeclaringEntityType.DisplayName(), tableName, foreignKeyName, foreignKey.Properties.FormatColumns(), duplicateForeignKey.Properties.FormatColumns())); } if (!foreignKey.PrincipalKey.Properties .Select(p => p.Relational().ColumnName) .SequenceEqual( duplicateForeignKey.PrincipalKey.Properties .Select(p => p.Relational().ColumnName))) { throw new InvalidOperationException( RelationalStrings.DuplicateForeignKeyPrincipalColumnMismatch( Property.Format(foreignKey.Properties), foreignKey.DeclaringEntityType.DisplayName(), Property.Format(duplicateForeignKey.Properties), duplicateForeignKey.DeclaringEntityType.DisplayName(), tableName, foreignKeyName, foreignKey.PrincipalKey.Properties.FormatColumns(), duplicateForeignKey.PrincipalKey.Properties.FormatColumns())); } if (foreignKey.IsUnique != duplicateForeignKey.IsUnique) { throw new InvalidOperationException( RelationalStrings.DuplicateForeignKeyUniquenessMismatch( Property.Format(foreignKey.Properties), foreignKey.DeclaringEntityType.DisplayName(), Property.Format(duplicateForeignKey.Properties), duplicateForeignKey.DeclaringEntityType.DisplayName(), tableName, foreignKeyName)); } if (foreignKey.DeleteBehavior != duplicateForeignKey.DeleteBehavior) { throw new InvalidOperationException( RelationalStrings.DuplicateForeignKeyDeleteBehaviorMismatch( Property.Format(foreignKey.Properties), foreignKey.DeclaringEntityType.DisplayName(), Property.Format(duplicateForeignKey.Properties), duplicateForeignKey.DeclaringEntityType.DisplayName(), tableName, foreignKeyName, foreignKey.DeleteBehavior, duplicateForeignKey.DeleteBehavior)); } } }
/// <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> protected virtual void ValidateSharedTableCompatibility( [NotNull] IReadOnlyList <IEntityType> mappedTypes, [NotNull] string tableName) { if (mappedTypes.Count == 1) { return; } var firstValidatedType = mappedTypes[0]; var typesToValidate = new Queue <IEntityType>(); typesToValidate.Enqueue(firstValidatedType); var unvalidatedTypes = new HashSet <IEntityType>(mappedTypes.Skip(1)); while (typesToValidate.Count > 0) { var entityType = typesToValidate.Dequeue(); var typesToValidateLeft = typesToValidate.Count; var nextTypeSet = unvalidatedTypes.Where( unvalidatedType => entityType.RootType() == unvalidatedType.RootType() || IsIdentifyingPrincipal(entityType, unvalidatedType) || IsIdentifyingPrincipal(unvalidatedType, entityType)); foreach (var nextEntityType in nextTypeSet) { var key = entityType.FindPrimaryKey(); var otherKey = nextEntityType.FindPrimaryKey(); if (key.Relational().Name != otherKey.Relational().Name) { throw new InvalidOperationException( RelationalStrings.IncompatibleTableKeyNameMismatch( tableName, entityType.DisplayName(), nextEntityType.DisplayName(), key.Relational().Name, Property.Format(key.Properties), otherKey.Relational().Name, Property.Format(otherKey.Properties))); } typesToValidate.Enqueue(nextEntityType); } foreach (var typeToValidate in typesToValidate.Skip(typesToValidateLeft)) { unvalidatedTypes.Remove(typeToValidate); } } if (unvalidatedTypes.Count == 0) { return; } foreach (var invalidEntityType in unvalidatedTypes) { throw new InvalidOperationException( RelationalStrings.IncompatibleTableNoRelationship( tableName, invalidEntityType.DisplayName(), firstValidatedType.DisplayName(), Property.Format(invalidEntityType.FindPrimaryKey().Properties), Property.Format(firstValidatedType.FindPrimaryKey().Properties))); } }
protected override async Task ConsumeAsync( RelationalDataReader relationalReader, CancellationToken cancellationToken = default) { var commandPosition = 0; int rowsAffected; try { do { while (commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition] == ResultSetMapping.NoResultSet) { commandPosition++; } if (commandPosition < CommandResultSet.Count) { if (ModificationCommands[commandPosition].RequiresResultPropagation) { rowsAffected = 0; do { var tableModification = ModificationCommands[commandPosition]; if (!await relationalReader.ReadAsync(cancellationToken)) { throw new DbUpdateConcurrencyException( RelationalStrings.UpdateConcurrencyException( ModificationCommands.Count(m => m.RequiresResultPropagation), rowsAffected), ModificationCommands[commandPosition].Entries); } var valueBufferFactory = CreateValueBufferFactory(tableModification.ColumnModifications); tableModification.PropagateResults(valueBufferFactory.Create(relationalReader.DbDataReader)); rowsAffected++; }while (++commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition - 1] == ResultSetMapping.NotLastInResultSet); } else { var expectedRowsAffected = 1; while (++commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition - 1] == ResultSetMapping.NotLastInResultSet) { expectedRowsAffected++; } if (relationalReader.Read()) { rowsAffected = relationalReader.DbDataReader.GetInt32(0); if (rowsAffected != expectedRowsAffected) { throw new DbUpdateConcurrencyException( RelationalStrings.UpdateConcurrencyException(expectedRowsAffected, rowsAffected), ModificationCommands[commandPosition - 1].Entries); } } else { throw new DbUpdateConcurrencyException( RelationalStrings.UpdateConcurrencyException(1, 0), ModificationCommands[commandPosition - 1].Entries); } } } }while (commandPosition < CommandResultSet.Count && await relationalReader.DbDataReader.NextResultAsync(cancellationToken)); } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( RelationalStrings.UpdateStoreException, ex, ModificationCommands[commandPosition].Entries); } }
public void Throws_for_unrecognized_types() { var ex = Assert.Throws <InvalidOperationException>(() => new SqlServerTypeMapper(new RelationalTypeMapperDependencies()).GetMapping("magic")); Assert.Equal(RelationalStrings.UnsupportedType("magic"), ex.Message); }
protected override void Consume(RelationalDataReader reader) { var npgsqlReader = (NpgsqlDataReader)reader.DbDataReader; #pragma warning disable 618 Debug.Assert(npgsqlReader.Statements.Count == ModificationCommands.Count, $"Reader has {npgsqlReader.Statements.Count} statements, expected {ModificationCommands.Count}"); #pragma warning restore 618 var commandIndex = 0; try { while (true) { // Find the next propagating command, if any int nextPropagating; for (nextPropagating = commandIndex; nextPropagating < ModificationCommands.Count && !ModificationCommands[nextPropagating].RequiresResultPropagation; nextPropagating++) { } // Go over all non-propagating commands before the next propagating one, // make sure they executed for (; commandIndex < nextPropagating; commandIndex++) { #pragma warning disable 618 if (npgsqlReader.Statements[commandIndex].Rows == 0) { throw new DbUpdateConcurrencyException( RelationalStrings.UpdateConcurrencyException(1, 0), ModificationCommands[commandIndex].Entries ); } #pragma warning restore 618 } if (nextPropagating == ModificationCommands.Count) { Debug.Assert(!npgsqlReader.NextResult(), "Expected less resultsets"); break; } // Propagate to results from the reader to the ModificationCommand var modificationCommand = ModificationCommands[commandIndex++]; if (!reader.Read()) { throw new DbUpdateConcurrencyException( RelationalStrings.UpdateConcurrencyException(1, 0), modificationCommand.Entries); } var valueBufferFactory = CreateValueBufferFactory(modificationCommand.ColumnModifications); modificationCommand.PropagateResults(valueBufferFactory.Create(npgsqlReader)); npgsqlReader.NextResult(); } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( RelationalStrings.UpdateStoreException, ex, ModificationCommands[commandIndex].Entries); } }
public override async Task Include_collection_with_last_no_orderby(bool async) => Assert.Equal( RelationalStrings.LastUsedWithoutOrderBy(nameof(Enumerable.Last)), (await Assert.ThrowsAsync <InvalidOperationException>( () => base.Include_collection_with_last_no_orderby(async))).Message);