public virtual ModificationCommand AddEntry([NotNull] InternalEntityEntry entry) { Check.NotNull(entry, nameof(entry)); if (entry.EntityState != EntityState.Added && entry.EntityState != EntityState.Modified && entry.EntityState != EntityState.Deleted) { throw new NotSupportedException(Strings.ModificationFunctionInvalidEntityState(entry.EntityState)); } var firstEntry = _entries.FirstOrDefault(); if (firstEntry != null && firstEntry.EntityState != entry.EntityState) { // TODO: Proper message throw new InvalidOperationException("Two entities cannot make conflicting updates to the same row."); // TODO: Check for any other conflicts between the two entries } _entries.Add(entry); _columnModifications.Reset(GenerateColumnModifications); _valueBufferFactory.Reset(CreateValueBufferFactory); return(this); }
public virtual void Detects_missing_discriminator_property() { var model = new Entity.Metadata.Model(); var entityA = model.AddEntityType(typeof(A)); var entityC = model.AddEntityType(typeof(C)); entityC.BaseType = entityA; VerifyError(Strings.NoDiscriminatorProperty(entityC.DisplayName()), model); }
public virtual void Detects_duplicate_table_names() { var model = new Entity.Metadata.Model(); var entityA = model.AddEntityType(typeof(A)); var entityB = model.AddEntityType(typeof(B)); entityA.Relational().TableName = "Table"; entityB.Relational().TableName = "Table"; VerifyError(Strings.DuplicateTableName("Table", null, entityB.DisplayName()), model); }
public virtual RelationalTypeMapping GetDefaultMapping(Type clrType) { Check.NotNull(clrType, nameof(clrType)); RelationalTypeMapping mapping; if (SimpleMappings.TryGetValue(clrType.UnwrapEnumType(), out mapping)) { return(mapping); } throw new NotSupportedException(Strings.UnsupportedType(clrType.Name)); }
public virtual void Detects_missing_discriminator_value_on_leaf() { var model = new Entity.Metadata.Model(); var entityAbstract = model.AddEntityType(typeof(Abstract)); var entityGeneric = model.AddEntityType(typeof(Generic <string>)); entityGeneric.BaseType = entityAbstract; var discriminatorProperty = entityAbstract.AddProperty("D", typeof(int)); entityAbstract.Relational().DiscriminatorProperty = discriminatorProperty; entityAbstract.Relational().DiscriminatorValue = 0; VerifyError(Strings.NoDiscriminatorValue(entityGeneric.DisplayName()), model); }
public virtual void ApplyMigrations(string targetMigration = null) { var connection = _connection.DbConnection; _logger.Value.LogVerbose(Strings.UsingConnection(connection.Database, connection.DataSource)); var migrations = _migrationAssembly.Migrations; var appliedMigrationEntries = _historyRepository.GetAppliedMigrations(); var appliedMigrations = new List <Migration>(); var unappliedMigrations = new List <Migration>(); foreach (var migraion in migrations) { if (appliedMigrationEntries.Any( e => string.Equals(e.MigrationId, migraion.Id, StringComparison.OrdinalIgnoreCase))) { appliedMigrations.Add(migraion); } else { unappliedMigrations.Add(migraion); } } IEnumerable <Migration> migrationsToApply; IEnumerable <Migration> migrationsToRevert; if (string.IsNullOrEmpty(targetMigration)) { migrationsToApply = unappliedMigrations; migrationsToRevert = Enumerable.Empty <Migration>(); } else if (targetMigration == InitialDatabase) { migrationsToApply = Enumerable.Empty <Migration>(); migrationsToRevert = appliedMigrations; } else { targetMigration = _idGenerator.ResolveId(targetMigration, migrations); migrationsToApply = unappliedMigrations .Where(m => string.Compare(m.Id, targetMigration, StringComparison.OrdinalIgnoreCase) <= 0); migrationsToRevert = appliedMigrations .Where(m => string.Compare(m.Id, targetMigration, StringComparison.OrdinalIgnoreCase) > 0) .OrderByDescending(m => m.Id); } bool first; var checkFirst = true; foreach (var migration in migrationsToApply) { var batches = ApplyMigration(migration).ToList(); first = false; if (checkFirst) { first = migration == migrations[0]; if (first && !_historyRepository.Exists()) { // TODO: Consider removing check above and always using "if not exists" batches.Insert(0, new SqlBatch(_historyRepository.Create(ifNotExists: false))); } checkFirst = false; } _logger.Value.LogInformation(Strings.ApplyingMigration(migration.Id)); Execute(batches, first); } foreach (var migration in migrationsToRevert) { _logger.Value.LogInformation(Strings.RevertingMigration(migration.Id)); Execute(RevertMigration(migration)); } }
public virtual string ScriptMigrations( string fromMigrationName, string toMigrationName, bool idempotent = false) { var migrations = _migrationAssembly.Migrations; if (string.IsNullOrEmpty(fromMigrationName)) { fromMigrationName = InitialDatabase; } else if (fromMigrationName != InitialDatabase) { fromMigrationName = _idGenerator.ResolveId(fromMigrationName, migrations); } if (string.IsNullOrEmpty(toMigrationName)) { toMigrationName = migrations.Last().Id; } else if (toMigrationName != InitialDatabase) { toMigrationName = _idGenerator.ResolveId(toMigrationName, migrations); } var builder = new IndentedStringBuilder(); // If going up... if (string.Compare(fromMigrationName, toMigrationName, StringComparison.OrdinalIgnoreCase) <= 0) { var migrationsToApply = migrations.Where( m => string.Compare(m.Id, fromMigrationName, StringComparison.OrdinalIgnoreCase) > 0 && string.Compare(m.Id, toMigrationName, StringComparison.OrdinalIgnoreCase) <= 0); var checkFirst = true; foreach (var migration in migrationsToApply) { if (checkFirst) { if (migration == migrations[0]) { builder.AppendLine(_historyRepository.Create(ifNotExists: true)); builder.AppendLine(_sqlGenerator.BatchSeparator); builder.AppendLine(); } checkFirst = false; } _logger.Value.LogVerbose(Strings.GeneratingUp(migration.Id)); foreach (var batch in ApplyMigration(migration)) { if (idempotent) { builder.AppendLine(_historyRepository.BeginIfNotExists(migration.Id)); using (builder.Indent()) { var lines = batch.Sql.Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (var line in lines) { builder.AppendLine(line); } } builder.AppendLine(_historyRepository.EndIf()); } else { builder.Append(batch.Sql); } builder.AppendLine(_sqlGenerator.BatchSeparator); builder.AppendLine(); } } } else // If going down... { var migrationsToRevert = migrations .Where( m => string.Compare(m.Id, toMigrationName, StringComparison.OrdinalIgnoreCase) > 0 && string.Compare(m.Id, fromMigrationName, StringComparison.OrdinalIgnoreCase) <= 0) .OrderByDescending(m => m.Id); foreach (var migration in migrationsToRevert) { _logger.Value.LogVerbose(Strings.GeneratingDown(migration.Id)); foreach (var batch in RevertMigration(migration)) { if (idempotent) { builder.AppendLine(_historyRepository.BeginIfExists(migration.Id)); using (builder.Indent()) { var lines = batch.Sql.Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (var line in lines) { builder.AppendLine(line); } } builder.AppendLine(_historyRepository.EndIf()); } else { builder.Append(batch.Sql); } builder.AppendLine(_sqlGenerator.BatchSeparator); builder.AppendLine(); } } } return(builder.ToString()); }
public virtual void Migrate(string targetMigration = null) { var connection = _connection.DbConnection; _logger.Value.LogVerbose(Strings.UsingConnection(connection.Database, connection.DataSource)); var migrations = _migrationAssembly.Migrations; var appliedMigrationEntries = _historyRepository.GetAppliedMigrations(); var appliedMigrations = new List <Migration>(); var unappliedMigrations = new List <Migration>(); foreach (var migraion in migrations) { if (appliedMigrationEntries.Any( e => string.Equals(e.MigrationId, migraion.Id, StringComparison.OrdinalIgnoreCase))) { appliedMigrations.Add(migraion); } else { unappliedMigrations.Add(migraion); } } IReadOnlyList <Migration> migrationsToApply; IReadOnlyList <Migration> migrationsToRevert; if (string.IsNullOrEmpty(targetMigration)) { migrationsToApply = unappliedMigrations; migrationsToRevert = new Migration[0]; } else if (targetMigration == Migration.InitialDatabase) { migrationsToApply = new Migration[0]; migrationsToRevert = appliedMigrations.OrderByDescending(m => m.Id).ToList(); } else { targetMigration = _migrationAssembly.GetMigration(targetMigration).Id; migrationsToApply = unappliedMigrations .Where(m => string.Compare(m.Id, targetMigration, StringComparison.OrdinalIgnoreCase) <= 0) .ToList(); migrationsToRevert = appliedMigrations .Where(m => string.Compare(m.Id, targetMigration, StringComparison.OrdinalIgnoreCase) > 0) .OrderByDescending(m => m.Id) .ToList(); } bool first; var checkFirst = true; foreach (var migration in migrationsToApply) { var batches = new List <SqlBatch>(GenerateUpSql(migration)); first = false; if (checkFirst) { first = migration == migrations[0]; if (first && !_historyRepository.Exists()) { // TODO: Prepend to first batch instead batches.Insert(0, new SqlBatch(_historyRepository.GetCreateScript())); } checkFirst = false; } _logger.Value.LogInformation(Strings.ApplyingMigration(migration.Id)); Execute(batches, first); } for (var i = 0; i < migrationsToRevert.Count; i++) { var migration = migrationsToRevert[i]; _logger.Value.LogInformation(Strings.RevertingMigration(migration.Id)); Execute(GenerateDownSql( migration, i != migrationsToRevert.Count - 1 ? migrationsToRevert[i + 1] : null)); } }
public virtual string GenerateScript( string fromMigration, string toMigration, bool idempotent = false) { var migrations = _migrationAssembly.Migrations; if (string.IsNullOrEmpty(fromMigration)) { fromMigration = Migration.InitialDatabase; } else if (fromMigration != Migration.InitialDatabase) { fromMigration = _migrationAssembly.GetMigration(fromMigration).Id; } if (string.IsNullOrEmpty(toMigration)) { toMigration = migrations.Last().Id; } else if (toMigration != Migration.InitialDatabase) { toMigration = _migrationAssembly.GetMigration(toMigration).Id; } var builder = new IndentedStringBuilder(); // If going up... if (string.Compare(fromMigration, toMigration, StringComparison.OrdinalIgnoreCase) <= 0) { var migrationsToApply = migrations.Where( m => string.Compare(m.Id, fromMigration, StringComparison.OrdinalIgnoreCase) > 0 && string.Compare(m.Id, toMigration, StringComparison.OrdinalIgnoreCase) <= 0); var checkFirst = true; foreach (var migration in migrationsToApply) { if (checkFirst) { if (migration == migrations[0]) { builder.AppendLine(_historyRepository.GetCreateIfNotExistsScript()); builder.AppendLine(_sql.BatchSeparator); builder.AppendLine(); } checkFirst = false; } _logger.Value.LogVerbose(Strings.GeneratingUp(migration.Id)); foreach (var batch in GenerateUpSql(migration)) { if (idempotent) { builder.AppendLine(_historyRepository.GetBeginIfNotExistsScript(migration.Id)); using (builder.Indent()) { builder.AppendLines(batch.Sql); } builder.AppendLine(_historyRepository.GetEndIfScript()); } else { builder.Append(batch.Sql); } builder.AppendLine(_sql.BatchSeparator); builder.AppendLine(); } } } else // If going down... { var migrationsToRevert = migrations .Where( m => string.Compare(m.Id, toMigration, StringComparison.OrdinalIgnoreCase) > 0 && string.Compare(m.Id, fromMigration, StringComparison.OrdinalIgnoreCase) <= 0) .OrderByDescending(m => m.Id) .ToList(); for (var i = 0; i < migrationsToRevert.Count; i++) { var migration = migrationsToRevert[i]; var previousMigration = i != migrationsToRevert.Count - 1 ? migrationsToRevert[i + 1] : null; _logger.Value.LogVerbose(Strings.GeneratingDown(migration.Id)); foreach (var batch in GenerateDownSql(migration, previousMigration)) { if (idempotent) { builder.AppendLine(_historyRepository.GetBeginIfExistsScript(migration.Id)); using (builder.Indent()) { builder.AppendLines(batch.Sql); } builder.AppendLine(_historyRepository.GetEndIfScript()); } else { builder.Append(batch.Sql); } builder.AppendLine(_sql.BatchSeparator); builder.AppendLine(); } } } return(builder.ToString()); }
protected virtual RelationalTypeMapping GetCustomMapping([NotNull] IProperty property) { Check.NotNull(property, nameof(property)); throw new NotSupportedException(Strings.UnsupportedType(property.ClrType.Name)); }