Fusionar MyDbContext con IdentityDbContext

Tengo un MyDbContext en un proyecto de biblioteca de clases Data Accass Layer separado. Y tengo un proyecto ASP.NET MVC 5 con un IdentityDbContext predeterminado. Los dos contextos usan la misma base de datos, y quiero usar la tabla AspNetUsers a la clave externa para algunas de mis tablas. Así que me gustaría fusionar los dos Context y también quiero usar ASP.NET Identity.

¿Cómo puedo hacer esto?

Por favor aconséjame,

Este es mi contexto después de la fusión:

public class CrmContext : IdentityDbContext //DbContext { public class ApplicationUser : IdentityUser { public Int16 Area { get; set; } public bool Holiday { get; set; } public bool CanBePublic { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public CrmContext() : base("DefaultConnection") { } public DbSet Case { get; set; } public DbSet CaseLog { get; set; } public DbSet Comment { get; set; } public DbSet Parameter { get; set; } public DbSet Sign { get; set; } public DbSet Template { get; set; } public DbSet Read { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove(); } } 

Aquí está mi clase RepositoryBase:

  public class RepositoryBase : IRepositoryBaseAsync, IDisposable where TContext : IdentityDbContext //DbContext where TEntity : class { private readonly TContext _context; private readonly IObjectSet _objectSet; protected TContext Context { get { return _context; } } public RepositoryBase(TContext context) { if (context != null) { _context = context; //Here it is the error: _objectSet = (_context as IObjectContextAdapter).ObjectContext.CreateObjectSet(); } else { throw new NullReferenceException("Context cannot be null"); } } } 

Se produjo una excepción del tipo 'System.Data.Entity.ModelConfiguration.ModelValidationException' en EntityFramework.dll, pero no se manejó en el código de usuario

Información adicional : se detectaron uno o más errores de validación durante la generación del modelo:

Actualización: encontré la solución.

Tuve que eliminar esta convención de nombres:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove(); } 

Y migre el modelo ef cf a db, para cambiar el nombre de mis tablas con las convenciones de nombre de la identidad asp.net. ¡Está trabajando ahora!

  1. Mueva la definición ApplicationUser a su DAL.
  2. MyDbContext su MyDbContext de IdentityDbContext o IdentityDbContext
  3. OnModelCreating: proporcione la información de la clave externa.
  4. Pase MyDbContext mientras crea el UserManager

Puede obtener el siguiente mensaje si sigue los pasos anteriores pero no puede encontrar la forma de proporcionar la información clave. El error que puede recibir es:

IdentityUserLogin:: EntityType ‘IdentityUserLogin’ no tiene una clave definida. Defina la clave para este EntityType. Context.IdentityUserRole:: EntityType ‘IdentityUserRole’ no tiene una clave definida. Defina la clave para este EntityType.

Crea las dos siguientes clases

 public class IdentityUserLoginConfiguration : EntityTypeConfiguration { public IdentityUserLoginConfiguration() { HasKey(iul => iul.UserId); } } public class IdentityUserRoleConfiguration : EntityTypeConfiguration { public IdentityUserRoleConfiguration() { HasKey(iur => iur.RoleId); } } 

En el método OnModelCreating dentro de sus Aplicaciones DbContext agregue las dos configuraciones descritas anteriormente al modelo:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration()); modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration()); } 

Esto ahora debería deshacerse de los métodos de error cuando se está creando su modelo. Lo hizo por mi

Puede que este sea un hilo antiguo, pero este artículo fue muy útil para demostrar cómo funciona la solución a la pregunta anterior: http://blogs.msdn.com/b/webdev/archive/2014/03/20/test- announcecing-rtm-of-asp-net-identity-2-0-0.aspx

Terminé teniendo que incluir

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //.... } 

porque sin él, obtendría el siguiente error:

EntityType ‘IdentityUserRole’ no tiene una clave definida. Defina la clave para este EntityType. EntityType ‘IdentityUserLogin’ no tiene una clave definida. Defina la clave para este EntityType. EntitySet ‘IdentityUserRoles’ se basa en el tipo ‘IdentityUserRole’ que no tiene claves definidas. EntitySet ‘IdentityUserLogins’ se basa en el tipo ‘IdentityUserLogin’ que no tiene claves definidas.

Si agrego estas configuraciones como se menciona arriba:

 public class IdentityUserLoginConfiguration : EntityTypeConfiguration { public IdentityUserLoginConfiguration() { HasKey(iul => iul.UserId); } } public class IdentityUserRoleConfiguration : EntityTypeConfiguration { public IdentityUserRoleConfiguration() { HasKey(iur => iur.RoleId); } } 

crearía una clave externa adicional llamada Application_User.

1) Después de heredar el contexto de IdentityDbContext, los errores relacionados con las claves primarias en las tablas de identidad (AspNetUsers, etc.) deberían desaparecer.

2) Su extensión ApplicationUser de IdentityUser le falta propiedades de navegación que Entity Framework interpreta como claves foráneas (estas también son muy útiles para navegar desde su código).

 public class ApplicationUser : IdentityUser { public Int16 Area { get; set; } public bool Holiday { get; set; } public bool CanBePublic { get; set; } public string FirstName { get; set; } public string LastName { get; set; } //*** Add the following for each table that relates to ApplicationUser (here 1-to-many) public virtual IList Cases { get; set; } //Navigation property //*** and inside the case class you should have //*** both a public ApplicationUser ApplicationUser {get;set;} //*** and a public string ApplicationUserId {get;set;} (string because they use GUID not int) } 

3) Leí en muchos lugares que cuando superas OnModelCreating, tienes que llamar al método base. Parece que a veces puedes prescindir de eso.

  protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //.... } 

He dado una respuesta completa a esta pregunta aquí . Aquí está la respuesta corta:

Basado en el código fuente IdentityDbContext si queremos fusionar IdentityDbContext con nuestro DbContext, tenemos dos opciones:

Primera opción:
Cree un DbContext que herede de IdentityDbContext y tenga acceso a las clases.

  public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection") { } static ApplicationDbContext() { Database.SetInitializer(new ApplicationDbInitializer()); } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } // Add additional items here as needed } 

Segunda opción: (No recomendado)
En realidad, no tenemos que heredar de IdentityDbContext si escribimos todo el código nosotros mismos.
Básicamente, podemos heredar de DbContext e implementar nuestra versión personalizada de “OnModelCreating (generador de ModelBuilder)” del código fuente de IdentityDbContext

Intenté de una manera simple … copie la cadena de conexión de su db y reemplace la cadena de conexión de DefaultConnection. Adelante y crear usuario, todas las tablas necesarias se crean automáticamente en su base de datos.

Espero que ayude