1

Je reçois une exception lorsque j'essaie d'exécuter "Update-Database" à partir du Gestionnaire de packages. Cela se produit avec et sans migration échafaudée.Erreur: nom d'objet incorrect 'dbo .__ MigrationHistory'. avec un nom de schéma personnalisé

Je donne les résultats suivants:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 

    modelBuilder.HasDefaultSchema("final"); 
    ... 
    ... 
} 

Je venais de créer cette base de données et a fait quelques mises à jour, et les choses allaient bien. EF place la table __MigrationsHistory dans le schéma "final" comme il se doit (final .__ MigrationsHistory). Mais à un moment donné, j'ai fait une "base de données de mise à jour" et j'ai eu l'erreur ci-dessous.

Je pense que je peux voir ce qui ne va pas dans le script SQL autogénéré d'EF. Je pense que la dernière ligne (la ligne qui a provoqué l'exception) devrait vérifier l'existence de l'objet dbo__MigrationsHistory avant qu'il ne tente de le supprimer. Ou vérifiez simplement l'existence de dbo__MigrationsHistory avant d'essayer de déplacer son contenu dans la table Historique de la migration du schéma personnalisé. Pour une raison quelconque, EF pensait avoir une table dbo .__ MigrationsHistory quand je ne l'ai jamais fait. Donc, je pense que c'est un bug dans EF. J'utilise EF 6.1.3.

Peut-être que quelqu'un sait à ce sujet.

est ici la fin du autogenerated script de migration SQL ...

... 
IF object_id('final.__MigrationHistory') IS NULL BEGIN 
     CREATE TABLE [final].[__MigrationHistory] (
      [MigrationId] [nvarchar](150) NOT NULL, 
      [ContextKey] [nvarchar](300) NOT NULL, 
      [Model] [varbinary](max) NOT NULL, 
      [ProductVersion] [nvarchar](32) NOT NULL, 
      CONSTRAINT [PK_final.__MigrationHistory] PRIMARY KEY ([MigrationId], [ContextKey]) 
     ) 
    END 
    INSERT INTO [final].[__MigrationHistory] 
    SELECT * FROM [dbo].[__MigrationHistory] 
    WHERE [ContextKey] = 'MyNamespace.Migrations.Configuration' 
    DELETE [dbo].[__MigrationHistory] 
    WHERE [ContextKey] = 'MyNamespace.Migrations.Configuration' 
    IF NOT EXISTS(SELECT * FROM [dbo].[__MigrationHistory]) 
     DROP TABLE [dbo].[__MigrationHistory] 
    System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'dbo.__MigrationHistory'. 
     at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
     at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
     at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
     at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
     at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) 
     at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) 
     at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
     at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c) 
     at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
     at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext) 
     at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery() 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinTransaction(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinNewTransaction(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection) 
     at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e() 
     at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0() 
     at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
     at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto) 
     at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
     at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
     at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration) 
     at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b() 
     at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) 
     at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 
     at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run() 
     at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
     at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
     at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 
     at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force) 
     at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0() 
     at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) 
    ClientConnectionId:ff9329dc-c707-43bd-b2da-78f4e41ba3d6 
    Error Number:208,State:1,Class:16 
    Invalid object name 'dbo.__MigrationHistory'. 

Répondre

1

Eh bien, il existe une solution.

Si vous ajoutez un fichier à votre projet avec le code suivant, les choses vont fonctionner.

using System.Data.Entity; 
using System.Data.Entity.Migrations.History; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace MyNamespace.Migrations 
{ 
    public class CustomHistoryContext : HistoryContext 
    { 
     public CustomHistoryContext(DbConnection dbConnection, string defaultSchema) 
      : base(dbConnection, defaultSchema) 
     { 
     } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 
      modelBuilder.Entity<HistoryRow>().ToTable(tableName: "__MigrationHistory", schemaName: "dbo"); 
      //modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID"); 
     } 
    } 

    public class CustomHistoryConfiguration : DbConfiguration 
    { 
     public CustomHistoryConfiguration() 
     { 
      this.SetHistoryContext("System.Data.SqlClient", 
       (connection, defaultSchema) => new CustomHistoryContext(connection, defaultSchema)); 
     } 
    } 
} 

Je suis d'ici: http://blog.oneunicorn.com/2012/02/27/code-first-migrations-making-__migrationhistory-not-a-system-table/

Le code ci-dessus provoque EF pour mettre votre table MigrationsHistory/entrées dans le schéma dbo - même si vous utilisez un autre schéma que votre défaut.