Estoy trabajando con Entity Framework Code First y MVC 5. Cuando creé mi aplicación con autenticación de cuentas de usuario individual, me dieron un controlador de cuenta y, junto con él, todas las clases y el código necesarios para que la autenticación de cuentas de usuario indiv funcione. .
Entre el código que ya estaba en vigor estaba este:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("DXContext", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Pero luego seguí adelante y creé mi propio contexto usando código primero, así que ahora también tengo lo siguiente:
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; }
}
Finalmente, tengo el siguiente método de semilla para agregar algunos datos con los que trabajar mientras desarrollo:
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);
}
}
}
}
Mi solución se compila bien, pero cuando intento acceder a un controlador que requiere acceso a la base de datos, aparece el siguiente error:
DX.DOMAIN.Context.IdentityUserLogin:: EntityType 'IdentityUserLogin' no tiene una clave definida. Defina la clave para este EntityType.
DX.DOMAIN.Context.IdentityUserRole:: EntityType 'IdentityUserRole' no tiene una clave definida. Defina la clave para este EntityType.
¿Qué estoy haciendo mal? ¿Es porque tengo dos contextos?
ACTUALIZAR
Después de leer la respuesta de Augusto, opté por la opción 3 . Así es como se ve mi clase DXContext ahora:
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();
}
}
También agregué una User.cs
y una Role.cs
clase, se ven así:
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; }
}
No estaba seguro de si necesitaría una propiedad de contraseña en el usuario, ¡ya que el ApplicationUser predeterminado tiene eso y muchos otros campos!
De todos modos, el cambio anterior se construye bien, pero nuevamente aparece este error cuando se ejecuta la aplicación:
Nombre de columna no válido UserId
UserId
es una propiedad entera en mi Artist.cs