Il y a déjà un objet nommé "AspNetRoles" dans la base de données
il y a quelque temps, j'ai créé un ASP.NET MVC 5 site Web avec la version D'identité 1.0, et j'ai créé les tables D'identité avec ce projet. Maintenant je dois faire un autre site Web en utilisant la même base de données pour l'authentification, mais maintenant la version D'identité est 2.0. Donc, quand j'essaie de m'authentifier sur le nouveau site web, j'obtiens des erreurs.
J'essaie de migrer la base de données en utilisant L'approche Migrations, mais c'est confus et je reçois cette erreur There is already an object named 'AspNetRoles' in the database.
quand je tape Update-Database dans le PM console.
ma question Est, Comment est la meilleure façon d'utiliser la même base de données pour l'authentification des deux sites (l'un utilisant la version d'identité 1.0 et l'autre utilisant 2.0). Ai-je vraiment besoin de migrer la base de données?
Si oui, comment puis-je résoudre cette erreur que je suis?
2 réponses
Add-Migration InitialMigrations -IgnoreChanges
cela devrait générer un fichier "migration initiale" vierge. Maintenant, ajoutez tous les changements désirés à la classe que vous voulez. Une fois les modifications ajoutées, Lancez à nouveau la commande update:
update-database -verbose
Maintenant, la migration automatique sera appliquée et la table sera modifié avec vos modifications.
Edit: Voici une solution pour migrer l'identité 1 à 2 Upgrading from ASP.NET.Identité 1,0 à 2,0 Utilisez cette migration manuelle
public override void Up()
{
RenameColumn(table: "dbo.AspNetUserClaims", name: "User_Id", newName: "UserId");
RenameIndex(table: "dbo.AspNetUserClaims", name: "IX_User_Id", newName: "IX_UserId");
DropPrimaryKey("dbo.AspNetUserLogins");
AddColumn("dbo.AspNetUsers", "Email", c => c.String(maxLength: 256));
AddColumn("dbo.AspNetUsers", "EmailConfirmed", c => c.Boolean(nullable: false));
AddColumn("dbo.AspNetUsers", "PhoneNumber", c => c.String());
AddColumn("dbo.AspNetUsers", "PhoneNumberConfirmed", c => c.Boolean(nullable: false));
AddColumn("dbo.AspNetUsers", "TwoFactorEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.AspNetUsers", "LockoutEndDateUtc", c => c.DateTime());
AddColumn("dbo.AspNetUsers", "LockoutEnabled", c => c.Boolean(nullable: false));
AddColumn("dbo.AspNetUsers", "AccessFailedCount", c => c.Int(nullable: false));
AlterColumn("dbo.AspNetUsers", "UserName", c => c.String(nullable: false, maxLength: 256));
AlterColumn("dbo.AspNetUsers", "FirstName", c => c.String(nullable: false));
AlterColumn("dbo.AspNetUsers", "LastName", c => c.String(nullable: false));
AddColumn("dbo.AspNetUsers", "CreatedDateTime", c => c.DateTime(nullable: false));
AlterColumn("dbo.AspNetRoles", "Name", c => c.String(nullable: false, maxLength: 256));
AddPrimaryKey("dbo.AspNetUserLogins", new[] { "LoginProvider", "ProviderKey", "UserId" });
CreateIndex("dbo.AspNetUsers", "UserName", unique: true, name: "UserNameIndex");
CreateIndex("dbo.AspNetRoles", "Name", unique: true, name: "RoleNameIndex");
DropColumn("dbo.AspNetUsers", "Discriminator");
}
alors que vous pouvez (depuis EF6) utiliser les migrations dans deux projets distincts pour la même base de données, il ne peut y avoir aucun chevauchement. La façon dont les migrations fonctionnent est à travers un dbo._MigrationHistory
table qui stocke le contexte qui a généré la migration et l'État modèle de votre application, qui inclut les modèles D'identité.
lorsque vous essayez de connecter votre deuxième application, elle ne trouve aucune migration antérieure, et a donc besoin de générer sa migration initiale, qui inclura des tables pour le Modèles d'identité, qui sont dans son contexte. C'est là où est ton problème.
Pour les fins de l'Identité, vous devez choisir un projet à rendre le maître. Celui-ci utilisera un standard IdentityDbContext
où les modèles D'identité seront migrés.
l'autre projet devra être transformé en esclave, du moins en termes D'utilisation de L'identité. Ainsi, vous aurez besoin d'interagir avec au moins deux contextes dans cette application. On va être une sous-classe de IdentityDbContext
, mais traités en tant que base de données-première:
public class MyIdentityContext : IdentityDbContext<ApplicationUser>
{
public MyIdentityContext()
: base("ConnectionStringNameForYourSharedDB")
{
Database.SetInitializer<MyIdentityContext>(null);
}
}
L'autre contexte sera juste un DbContext
sous-classe qui sera migrée comme d'habitude. Vous devrez le répéter pour tout autre projet qui pourrait avoir besoin d'accéder aux mêmes renseignements D'identité provenant de la même base de données. En outre, en raison du code répétitif cela conduira à (et le fait que votre ApplicationUser
classe devra être partagé), vous devez déplacer ce code dans une bibliothèque de classe que chaque projet peut faire référence.