web-dev-qa-db-fra.com

Il y a déjà un objet nommé dans la base de données

La mise à jour de la base de données a échoué à partir de la console de Package Manager.

"Il y a déjà un objet nommé 'AboutUs' dans la base de données."

Comment puis-je résoudre ce problème?

internal sealed class Configuration 
    : DbMigrationsConfiguration<Jahan.Blog.Web.Mvc.Models.JahanBlogDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = false;
    }

    protected override void Seed(Jahan.Blog.Web.Mvc.Models.JahanBlogDbContext context)
    {

    }
}

Mon DbContext est:

public class JahanBlogDbContext : IdentityDbContext<User, Role, int, UserLogin, UserRole, UserClaim>
{
    public JahanBlogDbContext()
        : base("name=JahanBlogDbConnectionString")
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<JahanBlogDbContext>());
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Entity<Comment>().HasRequired(t => t.Article).WithMany(t => t.Comments).HasForeignKey(d => d.ArticleId).WillCascadeOnDelete(true);
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<User>().ToTable("User");
        modelBuilder.Entity<Role>().ToTable("Role");
        modelBuilder.Entity<UserRole>().ToTable("UserRole");
        modelBuilder.Entity<UserLogin>().ToTable("UserLogin");
        modelBuilder.Entity<UserClaim>().ToTable("UserClaim");
    }

    public virtual DbSet<Article> Articles { get; set; }
    public virtual DbSet<ArticleLike> ArticleLikes { get; set; }
    public virtual DbSet<ArticleTag> ArticleTags { get; set; }
    public virtual DbSet<AttachmentFile> AttachmentFiles { get; set; }
    public virtual DbSet<Comment> Comments { get; set; }
    public virtual DbSet<CommentLike> CommentLikes { get; set; }
    public virtual DbSet<CommentReply> CommentReplies { get; set; }
    public virtual DbSet<ContactUs> ContactUs { get; set; }
    public virtual DbSet<Project> Projects { get; set; }
    public virtual DbSet<ProjectState> ProjectStates { get; set; }
    public virtual DbSet<ProjectTag> ProjectTags { get; set; }
    public virtual DbSet<Rating> Ratings { get; set; }
    public virtual DbSet<Tag> Tags { get; set; }
    public virtual DbSet<AboutUs> AboutUs { get; set; }
}

Package Gérer la console:

PM> update-database -verbose -force
Using StartUp project 'Jahan.Blog.Web.Mvc'.
Using NuGet project 'Jahan.Blog.Web.Mvc'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'Jahan-Blog' (DataSource: (local), Provider: System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
Applying automatic migration: 201410101740197_AutomaticMigration.
CREATE TABLE [dbo].[AboutUs] (
    [Id] [int] NOT NULL IDENTITY,
    [Description] [nvarchar](max),
    [IsActive] [bit] NOT NULL,
    [CreatedDate] [datetime],
    [ModifiedDate] [datetime],
    CONSTRAINT [PK_dbo.AboutUs] PRIMARY KEY ([Id])
)
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'AboutUs' in the database.
   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(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbTransaction transaction, 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, XDocument targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
   at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
   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:88b66414-8776-45cd-a211-e81b2711c94b
There is already an object named 'AboutUs' in the database.
PM> 
87
Jahan

il semble qu'il y ait un problème dans le processus de migration, exécutez la commande add-migration dans "Package Manager Console":

Add-Migration Initial -IgnoreChanges

apportez quelques modifications, puis mettez à jour la base de données à partir du fichier "Initial":

Update-Database -verbose

Edit: - IgnoreChanges est dans EF6 mais pas dans EF Core, voici une solution de contournement: https://stackoverflow.com/a/43687656/495455

113
Sina Amirshekari

Peut-être avez-vous changé l'espace de noms dans votre projet!
Il existe dans votre base de données une table appeléedbo.__MigrationHistory. La table a une colonne appeléeContextKey.
La valeur de cette colonne est basée sur votrenamespace. par exemple est "DataAccess.Migrations.Configuration".
Lorsque vous modifiez l’espace de noms, des noms de tables en double avec des espaces de noms différents sont dupliqués.
Ainsi, après avoir modifié l’espace de noms côté code, modifiez-le également dans cette table de la base de données (pour toutes les lignes).
.__ Par exemple, si vous modifiez l'espace de nom en EFDataAccess, vous devez alors remplacer les valeurs de la colonne ContextKey dans dbo.__MigrationHistory par "EFDataAccess.Migrations.Configuration".
Ensuite, côté code, dans Outils => Package Manager Console, utilisez la commandeupdate-database.

Une autre option, au lieu de modifier la valeur de contexte dans la base de données, consiste à coder de manière irréversible la valeur de contexte de votre code sur l'ancienne valeur d'espace de nom. Ceci est possible en héritant de DbMigrationsConfiguration<YourDbContext> et dans le constructeur, affectez simplement l'ancienne valeur de contexte à ContextKey, puis héritez de MigrateDatabaseToLatestVersion<YourDbContext, YourDbMigrationConfiguration> et laissez cette classe vide. La dernière chose à faire est d’appeler Database.SetInitializer(new YourDbInitializer()); dans votre DbContext dans un constructeur statique.

J'espère que votre problème sera résolu.

60
Elnaz

"Il existe déjà un objet nommé 'AboutUs' dans la base de données."

Cette exception vous indique que quelqu'un a déjà ajouté un objet appelé "AboutUs" à la base de données. 

AutomaticMigrationsEnabled = true; peut y conduire car les versions de la base de données ne sont pas contrôlées par vous dans ce cas. Pour éviter les migrations imprévisibles et vous assurer que tous les développeurs de l'équipe travaillent avec la même structure de base de données je vous suggère de définir AutomaticMigrationsEnabled = false;.

Les migrations automatiques et les migrations codées peuvent coexister si vous êtes très prudent et que vous êtes le seul développeur d'un projet.

Vous trouverez une citation de l'article Automatic Code First Migrations sur Data Developer Center :

Automatic Migrations vous permet d'utiliser Code First Migrations sans avoir un fichier de code dans votre projet pour chaque modification que vous apportez. Pas tout les modifications peuvent être appliquées automatiquement - par exemple, les colonnes renommées requièrent l’utilisation d’une migration basée sur le code.

Recommandation pour les environnements d'équipe

Vous pouvez intercaler des migrations automatiques et basées sur du code, mais il s'agit de non recommandé dans les scénarios de développement en équipe. Si vous faites partie d'un équipe de développeurs qui utilisent le contrôle de source, vous devez soit utiliser des migrations purement automatiques ou des migrations purement codées. Compte tenu du limitations des migrations automatiques, nous vous recommandons d'utiliser migrations en environnement d'équipe.

16
Ilya Palkin

Dans mon cas, ma table EFMigrationsHistory a été vidée (d'une manière ou d'une autre) et lorsque j'essayais de lancer update-database, j'obtenais: 

Il y a déjà un objet nommé 'AspNetUsers' dans la base de données

Après avoir vu la table vide, il était logique d'essayer de réexécuter la migration initiale et de recréer les tables.

Pour résoudre ce problème, j'ai ajouté des lignes dans ma table EFMigrationsHistory. 1 ligne pour chaque migration pour laquelle je savais que la base de données était à jour.

Une ligne aura 2 colonnes: MigrationId et ProductVersion

MigrationId est le nom de votre fichier de migration. Exemple: 20170628112345_Initial

ProductVersion est la version ef que vous utilisez. Vous pouvez le trouver en tapant Get-Package dans la console du gestionnaire de packages et en recherchant votre paquet ef.

J'espère que c'est utile pour quelqu'un.

7
Kolby

Dans mon cas, j'avais renommé l'Assemblée qui contenait le modèle de structure d'entité code premier. Bien que le schéma actuel n’ait pas changé du tout, le tableau des migrations appelé

dbo.__MigrationHistory

contient une liste des migrations déjà effectuées sur la base du nom old Assembly. J'ai mis à jour l'ancien nom dans la table des migrations pour qu'il corresponde au nouveau et la migration a ensuite fonctionné à nouveau.

5
The Senator

Assurez-vous que votre projet de démarrage de solutions dispose de la chaîne de connexion correcte dans le fichier de configuration. Ou définissez le paramètre -StartUpProjectName lors de l'exécution de la commande update-database. Le paramètre -StartUpProjectName spécifie le fichier de configuration à utiliser pour les chaînes de connexion nommées. Si omis, le fichier de configuration du projet spécifié est utilisé. 

Voici un lien pour les références aux commandes ef-migration: __. http://coding.abel.nu/2012/03/ef-migrations-command-reference/

5
Ryan Layton

J'ai eu le même problème et après trois heures de lutte, je découvre ce qui se passe.

Dans mon cas, quand je voulais migrer pour la première fois dans la méthode up(), le code par défaut voulait créer les tables qui existaient déjà, alors j'ai la même erreur que vous.

Pour le résoudre, supprimez ce code et écrivez ce que vous voulez. Par exemple, je voulais ajouter une colonne alors je viens d'écrire

migrationBuilder.AddColumn<string>(
            name: "fieldName",
            table: "tableName",
            nullable: true);
2
arfa

Dans mon cas, le problème était dans Seeder. J'appelais _ctx.Database.EnsureCreated () à l'intérieur et, autant que je sache, la commande de mise à jour de la base de données a été exécutée avec succès, mais le seeder a essayé de créer la base de données "deuxième" fois.

Comment adresser:

  1. Effectuez une mise à jour de la série, lancez simplement l'application et appelez EnsureCreated (). La base de données sera créée/mise à jour
  2. Commentez ou supprimez le semoir.
1
Chekusty

Remarque: solution non recommandée. mais solution rapide dans certains cas.

Pour moi, dbo._MigrationHistory dans la base de production a manqué des enregistrements de migration lors du processus de publication, mais la base de développement contenait tous les enregistrements de migration.

Si vous êtes sûr que la base de données de production a un schéma identique et le plus récent comparé à la base de données dev, copier tous les enregistrements de migration dans la base de production peut résoudre le problème.

Vous pouvez faire dans VisualStudio uniquement.

  1. Ouvrez le panneau 'Explorateur d'objets SQL Server'> cliquez avec le bouton droit de la souris sur la table dbo._MigrationHistory de la base de données source (dans mon cas, db)> cliquez sur le menu "Comparaison des données ...".
  2. Ensuite, l’assistant de comparaison de données s’affiche, sélectionnez la base de données cible (dans mon cas, la base de données de production) et cliquez sur Suivant.
  3. Quelques secondes plus tard, certains enregistrements ne figureront que dans la base de données source. Cliquez simplement sur le bouton "Mettre à jour la cible".
  4. Dans le navigateur, cliquez sur le bouton d'actualisation pour voir le message d'erreur disparaître.

Notez que, encore une fois, il n'est pas recommandé dans un projet complexe et sérieux. Utilisez ceci uniquement si vous avez un problème lors de l’apprentissage ASP.Net ou EntityFramework.

1
Youngjae

Supprimer des lignes de la table dbo_MigrationHistory ou supprimer la table et exécuter

update-database -verbose

Toutes les migrations de votre projet seront exécutées une par une.

1
Ali Adravi

Après plus d'une heure sans résultats, j'ai essayé une autre approche, n'utilisant pas les migrations, mais j'ai comparé les schémas.

Dans Visual Studio -> Outils -> SQL Server -> Nouvelle comparaison de schémas

Tout d'abord, j'ai créé une nouvelle base de données entièrement nouvelle avec les migrations EF. Ensuite, j'ai comparé la nouvelle base de données avec celle que je voulais mettre à jour. Enfin généré un script de migration, et je pouvais effectuer une mise à jour du schéma.

0
FrankyHollywood

Dans mon cas (veux réinitialiser et obtenir une nouvelle base de données),

D'abord j'ai le message d'erreur: There is already an object named 'TABLENAME' in the database.

et j'ai vu un peu avant:

"Applying migration '20111111111111_InitialCreate'.
Failed executing DbCommand (16ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE MYFIRSTTABLENAME"

Ma base de données a été créée, mais aucun enregistrement dans l'historique des migrations.

Je laisse tomber toutes les tables sauf dbo .__ MigrationsHistory

MigrationsHistory était vide.

Exécuter dotnet ef database update -c StudyContext --verbose

(--verbose juste pour le plaisir)

et a obtenu Done.

0
JohnFI

Un autre scénario Edge-case EF Core.

Vérifiez que vous avez un fichier Migrations/YOURNAMEContextModelSnapshot.cs.

comme indiqué dans - https://docs.Microsoft.com/en-us/ef/core/managing-schemas/migrations/#create-a-migration

Si vous avez essayé de recréer manuellement votre base de données en supprimant les fichiers migration.cs, veillez à ce que votre fichier Migrations/* ContextModelSnapshot.cs existe toujours.

Sans cela, vos migrations ultérieures n'auront pas d'instantané sur lequel créer les différences requises et vos nouveaux fichiers de migration auront l'air de tout recréer à nouveau, vous obtiendrez alors l'erreur de table existante comme ci-dessus.

0
WickedW

Il suffit d’exécuter la commande update-migration -Script. Cela génère un nouveau script * .sql qui inclut toutes les modifications de base de données incluses dans la migration. À la fin du code, des commandes d'insertion ressemblent à ceci: INSERT [dbo]. [__ MigrationHistory] ([MigrationId], [ContextKey], [Model], [ProductVersion]), vous pouvez simplement l'exécuter tout cela. La base de données sera synchronisée 

0
Rasto