Je travaille avec Entity Framework Code First et MVC 5. Lorsque j'ai créé mon application avec l'authentification des comptes d'utilisateurs individuels, j'ai reçu un contrôleur de compte et avec lui toutes les classes et le code requis pour que l'authentification des comptes d'utilisateurs Indiv fonctionne .
Parmi les codes déjà en place, il y avait ceci:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("DXContext", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Mais ensuite, je suis allé de l'avant et j'ai d'abord créé mon propre contexte en utilisant du code, donc j'ai maintenant ce qui suit:
public class DXContext : DbContext
{
public DXContext() : base("DXContext")
{
}
public DbSet<ApplicationUser> Users { get; set; }
public DbSet<IdentityRole> Roles { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Paintings> Paintings { get; set; }
}
Enfin, j'ai la méthode de démarrage suivante pour ajouter des données avec lesquelles je pourrai travailler tout en développant:
protected override void Seed(DXContext context)
{
try
{
if (!context.Roles.Any(r => r.Name == "Admin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "Admin" };
manager.Create(role);
}
context.SaveChanges();
if (!context.Users.Any(u => u.UserName == "James"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser { UserName = "James" };
manager.Create(user, "ChangeAsap1@");
manager.AddToRole(user.Id, "Admin");
}
context.SaveChanges();
string userId = "";
userId = context.Users.FirstOrDefault().Id;
var artists = new List<Artist>
{
new Artist { FName = "Salvador", LName = "Dali", ImgURL = "http://i62.tinypic.com/ss8txxn.jpg", UrlFriendly = "salvador-dali", Verified = true, ApplicationUserId = userId },
};
artists.ForEach(a => context.Artists.Add(a));
context.SaveChanges();
var paintings = new List<Painting>
{
new Painting { Title = "The Persistence of Memory", ImgUrl = "http://i62.tinypic.com/xx8tssn.jpg", ArtistId = 1, Verified = true, ApplicationUserId = userId }
};
paintings.ForEach(p => context.Paintings.Add(p));
context.SaveChanges();
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
Ma solution se construit bien, mais lorsque j'essaie d'accéder à un contrôleur qui nécessite l'accès à la base de données, j'obtiens l'erreur suivante:
DX.DOMAIN.Context.IdentityUserLogin:: EntityType 'IdentityUserLogin' n'a pas de clé définie. Définissez la clé de cet EntityType.
DX.DOMAIN.Context.IdentityUserRole:: EntityType 'IdentityUserRole' n'a pas de clé définie. Définissez la clé de cet EntityType.
Qu'est-ce que je fais mal? Est-ce parce que j'ai deux contextes?
METTRE À JOUR
Après avoir lu la réponse d'Augusto, j'ai opté pour l' option 3 . Voici à quoi ressemble ma classe DXContext maintenant:
public class DXContext : DbContext
{
public DXContext() : base("DXContext")
{
// remove default initializer
Database.SetInitializer<DXContext>(null);
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Painting> Paintings { get; set; }
public static DXContext Create()
{
return new DXContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Role>().ToTable("Roles");
}
public DbQuery<T> Query<T>() where T : class
{
return Set<T>().AsNoTracking();
}
}
J'ai également ajouté une classe User.cs
et une Role.cs
classe, elles ressemblent à ceci:
public class User
{
public int Id { get; set; }
public string FName { get; set; }
public string LName { get; set; }
}
public class Role
{
public int Id { set; get; }
public string Name { set; get; }
}
Je n'étais pas sûr si j'aurais besoin d'une propriété de mot de passe sur l'utilisateur, car l'ApplicationUser par défaut a cela et un tas d'autres champs!
Quoi qu'il en soit, le changement ci-dessus se construit bien, mais encore une fois, j'obtiens cette erreur lorsque l'application est exécutée:
Nom de colonne non valide UserId
UserId
est une propriété entière sur mon Artist.cs
AddOrUpdate(new EntityObject { shoes = green})
également connu sous le nom de "upsert". par opposition à simplement ajouter au contexte, sinon vous ne créerez que des informations de contexte d'entité dupliquées / redondantes.Dans mon cas, j'avais hérité correctement de IdentityDbContext (avec mes propres types personnalisés et clé définis) mais j'avais supprimé par inadvertance l'appel à OnModelCreating de la classe de base:
Ce qui a ensuite corrigé mes index manquants dans les classes d'identité et j'ai pu alors générer des migrations et activer les migrations de manière appropriée.
la source
Pour ceux qui utilisent ASP.NET Identity 2.1 et ont changé la clé primaire de la valeur par défaut
string
à l'unint
ou l' autreGuid
, si vous obtenez toujoursvous avez probablement oublié de spécifier le nouveau type de clé sur
IdentityDbContext
:Si tu as juste
ou même
vous obtiendrez cette erreur «aucune clé définie» lorsque vous essayez d'ajouter des migrations ou de mettre à jour la base de données.
la source
En modifiant le DbContext comme ci-dessous;
Il suffit d' ajouter à l'
OnModelCreating
appel de méthode pour base.OnModelCreating (ModelBuilder); et ça devient bien. J'utilise EF6.Remerciements spéciaux à #The Senator
la source
la source
Mon problème était similaire - j'avais une nouvelle table que je créais et qui était liée aux utilisateurs d'identité. Après avoir lu les réponses ci-dessus, j'ai réalisé que cela avait à voir avec IsdentityUser et les propriétés héritées. J'avais déjà configuré Identity comme son propre contexte, donc pour éviter de lier intrinsèquement les deux, plutôt que d'utiliser la table utilisateur associée comme une véritable propriété EF, j'ai configuré une propriété non mappée avec la requête pour obtenir les entités associées. (DataManager est configuré pour récupérer le contexte actuel dans lequel OtherEntity existe.)
la source