Ich arbeite mit Entity Framework Code First und MVC 5. Als ich meine Anwendung mit der Authentifizierung einzelner Benutzerkonten erstellte, erhielt ich einen Kontocontroller und alle erforderlichen Klassen und Codes, die erforderlich sind, damit die Indiv-Benutzerkontenauthentifizierung funktioniert .
Zu den bereits vorhandenen Codes gehörte:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("DXContext", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Aber dann habe ich zuerst meinen eigenen Kontext mit Code erstellt, sodass ich jetzt auch Folgendes habe:
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; }
}
Schließlich habe ich die folgende Seed-Methode, um einige Daten hinzuzufügen, mit denen ich während der Entwicklung arbeiten kann:
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);
}
}
}
}
Meine Lösung funktioniert einwandfrei, aber wenn ich versuche, auf einen Controller zuzugreifen, der Zugriff auf die Datenbank erfordert, wird die folgende Fehlermeldung angezeigt:
DX.DOMAIN.Context.IdentityUserLogin :: EntityType 'IdentityUserLogin' hat keinen Schlüssel definiert. Definieren Sie den Schlüssel für diesen EntityType.
DX.DOMAIN.Context.IdentityUserRole :: Für EntityType 'IdentityUserRole' ist kein Schlüssel definiert. Definieren Sie den Schlüssel für diesen EntityType.
Was mache ich falsch? Liegt es daran, dass ich zwei Kontexte habe?
AKTUALISIEREN
Nachdem ich Augustos Antwort gelesen hatte, entschied ich mich für Option 3 . So sieht meine DXContext-Klasse jetzt aus:
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();
}
}
Ich habe auch eine User.cs
und eine Role.cs
Klasse hinzugefügt , sie sehen so aus:
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; }
}
Ich war mir nicht sicher, ob ich eine Kennworteigenschaft für den Benutzer benötigen würde, da der Standardanwendungsbenutzer diese und eine Reihe anderer Felder hat!
Wie auch immer, die obige Änderung funktioniert einwandfrei, aber ich erhalte erneut diesen Fehler, wenn die Anwendung ausgeführt wird:
Ungültiger Spaltenname UserId
UserId
ist eine ganzzahlige Eigenschaft auf meiner Artist.cs