226 votes

Comment puis-je modifier les noms des tables lorsque j'utilise ASP.NET Identity ?

J'utilise la version release (RTM, pas RC) de Visual Studio 2013 (téléchargée sur MSDN 2013-10-18) et donc la dernière version (RTM) d'AspNet.Identity. Lorsque je crée un nouveau projet web, je sélectionne "Comptes d'utilisateurs individuels" pour l'authentification. Cela crée les tableaux suivants :

  1. AspNetRoles
  2. AspNetUserClaims
  3. AspNetUserLogins
  4. AspNetUserRoles
  5. AspNetUsers

Lorsque j'enregistre un nouvel utilisateur (en utilisant le modèle par défaut), ces tables (listées ci-dessus) sont créées et la table AspNetUsers a un enregistrement inséré qui contient :

  1. Id
  2. Nom d'utilisateur
  3. PasswordHash
  4. Timbre de sécurité
  5. Discriminateur

De plus, en ajoutant des propriétés publiques à la classe "ApplicationUser", j'ai réussi à ajouter des champs supplémentaires à la table AspNetUsers, tels que "FirstName", "LastName", "PhoneNumber", etc.

Voici ma question. Existe-t-il un moyen de modifier le nom des tables ci-dessus (lors de leur création initiale) ou seront-elles toujours nommées avec l'identifiant AspNet préfixe comme je l'ai indiqué ci-dessus ? Si les noms des tables peuvent être nommés différemment, veuillez expliquer comment.

-- UPDATE --

J'ai mis en œuvre la solution de @Hao Kung. Elle crée bien une nouvelle table (par exemple, je l'ai appelée MyUsers), mais elle crée aussi toujours la table AspNetUsers. L'objectif est de remplacer la table "AspNetUsers" par la table "MyUsers". Voir le code ci-dessous et l'image de la base de données des tables créées.

Je voudrais en fait remplacer chaque AspNet table avec mon propre nom... Par exemple, MyRoles, MyUserClaims, MyUserLogins, MyUserRoles, et MyUsers.

Comment puis-je réaliser cela et me retrouver avec un seul jeu de tableaux ?

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string PhonePrimary { get; set; }
    public string PhoneSecondary { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(): base("DefaultConnection")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUser>().ToTable("MyUsers");
    }
}

Database Tables

-- RÉPONSE À LA MISE À JOUR --

Merci à Hao Kung et Peter Stulinski. Cela a résolu mon problème...

    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
        modelBuilder.Entity<ApplicationUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
        modelBuilder.Entity<IdentityUserRole>().ToTable("MyUserRoles");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("MyUserLogins");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("MyUserClaims");
        modelBuilder.Entity<IdentityRole>().ToTable("MyRoles");
    }

0 votes

Êtes-vous sûr ? Veuillez supprimer toutes vos tables, supprimez votre table _migration et essayez ensuite. Le code que j'ai posté ci-dessous, qui est très similaire au vôtre, ne crée pas la table AspNetUsers.

0 votes

Pour m'en assurer, j'ai supprimé toute la base de données, et même créé un nouveau projet web c# dans Visual Studio. Il crée toutes les tables AspNet et également la table MyUsers (comme illustré ci-dessus). Il crée la table _MigrationHistory et il y a un enregistrement inséré avec un MigrationId : "201310292106426_InitialCreate"

1 votes

La seule différence entre votre code et le mien est que j'ai renommé ApplicationUser en "User". Mon comportement est très différent. Lors de la première création, les tables sont créées selon les besoins et avec les noms que j'ai spécifiés..... Peut-être juste pour "l'expérimentation" essayez de changer ApplicationUser en User et ensuite ajoutez les lignes base.OnModelCreating(modelBuilder) ; modelBuilder.Entity<IdentityUser>() .ToTable("Users", "dbo") ; modelBuilder.Entity<ApplicationUser>() .ToTable("Users", "dbo") ;

131voto

Peter Stulinski Points 677

Vous pouvez le faire facilement en modifiant le fichier IdentityModel.cs comme indiqué ci-dessous :

Remplacez OnModelCreating dans votre DbContext puis ajoutez ce qui suit, cela changera la table AspNetUser en "Users" ; vous pouvez également changer les noms des champs ; la colonne Id par défaut deviendra User_Id.

modelBuilder.Entity<IdentityUser>()
                    .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");

ou simplement le texte ci-dessous si vous souhaitez conserver tous les noms de colonnes standard :

modelBuilder.Entity<IdentityUser>()
                        .ToTable("Users", "dbo")

Dans l'exemple complet ci-dessous (qui doit se trouver dans votre fichier IdentityModel.cs), j'ai modifié ma classe ApplicationUser pour qu'elle s'appelle User.

public class User : IdentityUser
    {
        public string PasswordOld { get; set; }
        public DateTime DateCreated { get; set; }

        public bool Activated { get; set; }

        public bool UserRole { get; set; }

    }

public class ApplicationDbContext : IdentityDbContext<User>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<IdentityUser>()
                .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
            modelBuilder.Entity<User>()
                .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
        }
    }

Veuillez noter que je n'ai pas réussi à faire fonctionner ceci si la table actuelle existe. Notez également que toutes les colonnes que vous ne mettez pas en correspondance avec les colonnes par défaut seront créées.

J'espère que cela vous aidera.

3 votes

Pour que ces changements prennent effet, vous devez utiliser des migrations pour pousser les changements vers la base de données existante.

2 votes

Si vous faites cela, vos clés étrangères seront un peu étranges, je ne pense pas que vous soyez obligé de changer le nom de la table sur IdentityUser. Voir ceci SO post

1 votes

Juste une vérification supplémentaire, car cela m'a déjà surpris auparavant. Assurez-vous que l'appel à base.OnModelCreating est la première ligne de code dans la surcharge, sinon le reste des lignes est écrasé par la classe Identity de base.

65voto

Frank Myat Thu Points 803

Voici ma solution de travail :

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder); // This needs to go before the other rules!

        modelBuilder.Entity<ApplicationUser>().ToTable("User");
        modelBuilder.Entity<IdentityRole>().ToTable("Role");
        modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

Voir ce pour plus de détails

0 votes

Pouvez-vous le faire en spécifiant des attributs au lieu de l'api (laide) fluide ?

0 votes

J'ai fait une modification mineure car j'ai réussi à rétrograder cette réponse sans m'en rendre compte ! Également mis à jour pour utiliser la méthode préférée pour les liens comme celui-ci [text](link)

0 votes

J'ai créé un projet MVC vide, je l'ai exécuté une fois, et les tables nommées en asp ont été créées. J'ai ensuite ajouté cette modification mineure, supprimé toutes mes tables et le dossier de migration (pour ce que ça vaut) et j'ai exécuté mon code à nouveau, mais les tables ont refusé d'être renommées. J'ai alors créé un projet entièrement nouveau, j'ai apporté cette modification avant de l'exécuter, et maintenant cela fonctionne. Est-ce que j'ai raté quelque chose de très évident ?

15voto

Hao Kung Points 13035

Vous pouvez essayer de redéfinir cette méthode dans votre classe DbContext pour la faire correspondre à une table de votre choix :

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<IdentityUser>()
            .ToTable("AspNetUsers");

7 votes

N'oubliez pas d'appeler base.OnModelCreating(modelBuilder); ou le reste du modèle ne sera pas créé.

0 votes

J'ai mis à jour ma question après avoir mis en œuvre la solution de @Hao Kung mais le problème persiste, veuillez voir ma question éditée ci-dessus. Merci.

2voto

sgrysoft Points 66

Juste à titre de documentation, pour celui qui vient à ce poste sur les années anyears sur l'avenir, (comme moi XD), Toutes les réponses données jusqu'à mon commentaire sont justes, mais vous pouvez simplementfied avec cette méthode donnée par Alexandru Bucur sur son blog

         //But this method is not longer supported on netcore > 2.2, so I need to fix it
         foreach (var entityType in modelBuilder.Model.GetEntityTypes())
         {
            var table = entityType.Relational().TableName;
             if (table.StartsWith("AspNet"))
             {
                 entityType.Relational().TableName = table.Substring(6);
             }
         };

        //This is the functional way on NetCore > 2.2
        foreach (var entityType in modelBuilder.Model.GetEntityTypes())
        {
            var tableName = entityType.GetTableName();
            if (tableName.StartsWith("AspNet"))
            {
                entityType.SetTableName(tableName.Substring(6));
            }
        }

1 votes

Je pense que c'est une bonne réponse lorsque vous souhaitez changer tous les noms de table. Je ferais un changement très mineur à l'intérieur de la méthode SetTableName et ajouterais un préfixe comme ; entityType.SetTableName(newTableNamePrefix + tableName.Substring(6));

0 votes

Sera également utile

1voto

Arvand Points 157

Nous pouvons changer les noms de table par défaut d'asp.net Identity comme ceci :

    public class ApplicationDbContext : IdentityDbContext
    {    
        public ApplicationDbContext(): base("DefaultConnection")
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<IdentityUser>().ToTable("user");
            modelBuilder.Entity<ApplicationUser>().ToTable("user");

            modelBuilder.Entity<IdentityRole>().ToTable("role");
            modelBuilder.Entity<IdentityUserRole>().ToTable("userrole");
            modelBuilder.Entity<IdentityUserClaim>().ToTable("userclaim");
            modelBuilder.Entity<IdentityUserLogin>().ToTable("userlogin");
        }
    }

De plus, nous pouvons étendre chaque classe et ajouter n'importe quelle propriété aux classes comme 'IdentityUser', 'IdentityRole', ...

    public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
{
    public ApplicationRole() 
    {
        this.Id = Guid.NewGuid().ToString();
    }

    public ApplicationRole(string name)
        : this()
    {
        this.Name = name;
    }

    // Add any custom Role properties/code here
}

// Must be expressed in terms of our custom types:
public class ApplicationDbContext 
    : IdentityDbContext<ApplicationUser, ApplicationRole, 
    string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    static ApplicationDbContext()
    {
        Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    // Add additional items here as needed
}

Pour gagner du temps, nous pouvons utiliser Modèle de projet extensible AspNet Identity 2.0 pour étendre toutes les classes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X