¿Es posible utilizar la nueva identidad de Asp.net con Database First y EDMX? ¿O solo con el código primero?
Esto es lo que hice:
1) Hice un nuevo proyecto MVC5 e hice que la nueva identidad creara las nuevas tablas de usuarios y roles en mi base de datos.
2) Luego abrí mi archivo Database First EDMX y lo arrastré en la nueva tabla Identity Users ya que tengo otras tablas que se relacionan con ella.
3) Al guardar el EDMX, el generador de POCO de Database First creará automáticamente una clase de usuario. Sin embargo, UserManager y RoleManager esperan una clase de usuario heredada del nuevo espacio de nombres de identidad (Microsoft.AspNet.Identity.IUser), por lo que el uso de la clase de usuario de POCO no funcionará.
Supongo que una posible solución es editar mis clases de generación de POCO para que mi clase de usuario herede de IUser.
¿O ASP.NET Identity solo es compatible con Code First Design?
++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++
Actualización: Siguiendo la sugerencia de Anders Abel a continuación, esto es lo que hice. Funciona, pero me pregunto si hay una solución más elegante.
1) Extendí la clase de usuario de mi entidad creando una clase parcial dentro del mismo espacio de nombres que mis entidades generadas automáticamente.
namespace MVC5.DBFirst.Entity
{
public partial class AspNetUser : IdentityUser
{
}
}
2) Cambié mi DataContext para heredar de IdentityDBContext en lugar de DBContext. Tenga en cuenta que cada vez que actualice su EDMX y vuelva a generar las clases DBContext y Entity, tendrá que volver a configurar esto.
public partial class MVC5Test_DBEntities : IdentityDbContext<AspNetUser> //DbContext
3) Dentro de su clase de entidad de usuario generada automáticamente, debe agregar la palabra clave de anulación a los siguientes 4 campos o comentar estos campos ya que se heredan de IdentityUser (Paso 1). Tenga en cuenta que cada vez que actualice su EDMX y vuelva a generar las clases DBContext y Entity, tendrá que volver a configurar esto.
override public string Id { get; set; }
override public string UserName { get; set; }
override public string PasswordHash { get; set; }
override public string SecurityStamp { get; set; }
fuente
Respuestas:
Debería ser posible usar el sistema de identidad con POCO y Database First, pero tendrá que hacer un par de ajustes:
partial
. Eso le permitirá proporcionar una implementación adicional en un archivo separado.User
clase en otro archivopartial User : IUser { }
Eso hará que la
User
clase implemente la interfaz correcta, sin tocar los archivos generados reales (editar archivos generados siempre es una mala idea).fuente
Mis pasos son muy similares pero quería compartirlos.
1) Crea un nuevo proyecto MVC5
2) Cree un nuevo Model.edmx. Incluso si es una base de datos nueva y no tiene tablas.
3) Edite web.config y reemplace esta cadena de conexión generada:
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-SSFInventory-20140521115734.mdf;Initial Catalog=aspnet-SSFInventory-20140521115734;Integrated Security=True" providerName="System.Data.SqlClient" />
con esta cadena de conexión:
<add name="DefaultConnection" connectionString="Data Source=.\SQLExpress;database=SSFInventory;integrated security=true;" providerName="System.Data.SqlClient" />
Luego, compile y ejecute la aplicación. Registre un usuario y luego se crearán las tablas.
fuente
EDITAR: ASP.NET Identity con EF Database First para MVC5 CodePlex Project Template.
Quería usar una base de datos existente y crear relaciones con ApplicationUser. Así es como lo hice usando SQL Server, pero la misma idea probablemente funcionaría con cualquier base de datos.
:base("DefaltConnection")
para usar el DbContext de su proyecto.Editar: Diagrama de clases de identidad Asp.Net
fuente
IdentityUser
no tiene valor aquí porque es el primer objeto de código utilizado por elUserStore
para la autenticación. Después de definir mi propioUser
objeto, implementé una clase parcial que implementa laIUser
que usa laUserManager
clase. Quería que miId
s fuera enint
lugar de una cadena, así que solo devuelvo el ID de usuario toString (). Del mismo modo que querían
enUsername
ser en minúsculas.public partial class User : IUser { public string Id { get { return this.UserID.ToString(); } } public string UserName { get { return this.Username; } set { this.Username = value; } } }
De ninguna manera lo necesitas
IUser
. Es solo una interfaz utilizada porUserManager
. Entonces, si desea definir un "IUser" diferente, tendrá que reescribir esta clase para usar su propia implementación.public class UserManager<TUser> : IDisposable where TUser: IUser
Ahora escribe el tuyo propio
UserStore
que maneja todo el almacenamiento de usuarios, reclamos, roles, etc. Implementa las interfaces de todo lo que hace el código primeroUserStore
y cambiawhere TUser : IdentityUser
awhere TUser : User
donde "Usuario" es tu objeto de entidad.public class MyUserStore<TUser> : IUserLoginStore<TUser>, IUserClaimStore<TUser>, IUserRoleStore<TUser>, IUserPasswordStore<TUser>, IUserSecurityStampStore<TUser>, IUserStore<TUser>, IDisposable where TUser : User { private readonly MyAppEntities _context; public MyUserStore(MyAppEntities dbContext) { _context = dbContext; } //Interface definitions }
Aquí hay un par de ejemplos sobre algunas de las implementaciones de la interfaz.
async Task IUserStore<TUser>.CreateAsync(TUser user) { user.CreatedDate = DateTime.Now; _context.Users.Add(user); await _context.SaveChangesAsync(); } async Task IUserStore<TUser>.DeleteAsync(TUser user) { _context.Users.Remove(user); await _context.SaveChangesAsync(); }
Usando la plantilla MVC 5, cambié el
AccountController
aspecto para que se vea así.public AccountController() : this(new UserManager<User>(new MyUserStore<User>(new MyAppEntities()))) { }
Ahora, el inicio de sesión debería funcionar con sus propias tablas.
fuente
Eche un vistazo a este proyecto en GitHub: https://github.com/KriaSoft/AspNet.Identity
Que incluye:
Vea también : Cómo crear un proveedor Database-First para ADO.NET Identity
fuente
Buena pregunta.
Soy más una persona de base de datos. El primer paradigma del código me parece que se me escapa y las "migraciones" parecen demasiado propensas a errores.
Quería personalizar el esquema de identidad de aspnet y no molestarme con las migraciones. Estoy bien versado en proyectos de bases de datos de Visual Studio (sqlpackage, data-dude) y cómo hace un buen trabajo actualizando esquemas.
Mi solución simplista es:
1) Cree un proyecto de base de datos que refleje el esquema de identidad de aspnet 2) use el resultado de este proyecto (.dacpac) como un recurso del proyecto 3) implemente el .dacpac cuando sea necesario
Para MVC5, la modificación de la
ApplicationDbContext
clase parece hacer que esto funcione ...1) Implementar
IDatabaseInitializer
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDatabaseInitializer<ApplicationDbContext> { ... }
2) En el constructor, indique que esta clase implementará la inicialización de la base de datos:
Database.SetInitializer<ApplicationDbContext>(this);
3) Implementar
InitializeDatabase
:Aquí, elegí usar DacFX e implementar mi .dacpac
void IDatabaseInitializer<ApplicationDbContext>.InitializeDatabase(ApplicationDbContext context) { using (var ms = new MemoryStream(Resources.Binaries.MainSchema)) { using (var package = DacPackage.Load(ms, DacSchemaModelStorageType.Memory)) { DacServices services = new DacServices(Database.Connection.ConnectionString); var options = new DacDeployOptions { VerifyDeployment = true, BackupDatabaseBeforeChanges = true, BlockOnPossibleDataLoss = false, CreateNewDatabase = false, DropIndexesNotInSource = true, IgnoreComments = true, }; services.Deploy(package, Database.Connection.Database, true, options); } } }
fuente
Pasé varias horas trabajando en esto y finalmente encontré una solución que he compartido en mi blog aquí . Básicamente, debe hacer todo lo que se dice en la respuesta de stink , pero con una cosa adicional: asegurarse de que Identity Framework tenga una cadena de conexión SQL-Client específica en la parte superior de la cadena de conexión de Entity Framework utilizada para las entidades de su aplicación.
En resumen, su aplicación utilizará una cadena de conexión para Identity Framework y otra para las entidades de su aplicación. Cada cadena de conexión es de un tipo diferente. Lea la publicación de mi blog para obtener un tutorial completo.
fuente
Descubrí que @ JoshYates1980 tiene la respuesta más simple.
Después de una serie de pruebas y errores, hice lo que Josh sugirió y reemplacé
connectionString
con mi cadena de conexión de base de datos generada. lo que me confundió originalmente fue la siguiente publicación:Cómo agregar la autenticación de identidad ASP.NET MVC5 a la base de datos existente
Donde la respuesta aceptada de @Win indicó cambiar el
ApplicationDbContext()
nombre de la conexión. Esto es un poco vago si está utilizando Entity y un primer enfoque de base de datos / modelo donde la cadena de conexión de la base de datos se genera y se agrega alWeb.config
archivo.El
ApplicationDbContext()
nombre de la conexión se asigna a la conexión predeterminada en elWeb.config
archivo. Por lo tanto, el método de Josh funciona mejor, pero para hacerloApplicationDbContext()
más legible, sugeriría cambiar el nombre por el nombre de su base de datos como @Win publicó originalmente, asegurándose de cambiar elconnectionString
de "DefaultConnection" enWeb.config
y comentar y / o eliminar la Entidad la base de datos generada incluye.Ejemplos de código:
fuente
Tenemos un proyecto de DLL de modelo de entidad en el que mantenemos nuestra clase de modelo. También mantenemos un proyecto de base de datos con todos los scripts de la base de datos. Mi enfoque fue el siguiente
1) Cree su propio proyecto que tenga el EDMX usando la base de datos primero
2) Script de las tablas en su base de datos, utilicé VS2013 conectado a localDB (Conexiones de datos) y copié el script en el proyecto de la base de datos, agregue cualquier columna personalizada, por ejemplo, Fecha de nacimiento [FECHA] no nula
3) Implementar la base de datos
4) Actualizar el proyecto de modelo (EDMX) Agregar al proyecto de modelo
5) Agregue cualquier columna personalizada a la clase de aplicación
public class ApplicationUser : IdentityUser { public DateTime BirthDate { get; set; } }
En el proyecto MVC, AccountController agregó lo siguiente:
El proveedor de identidad quiere una cadena de conexión SQL para que funcione, para mantener solo 1 cadena de conexión para la base de datos, extraiga la cadena del proveedor de la cadena de conexión EF
public AccountController() { var connection = ConfigurationManager.ConnectionStrings["Entities"]; var entityConnectionString = new EntityConnectionStringBuilder(connection.ConnectionString); UserManager = new UserManager<ApplicationUser>( new UserStore<ApplicationUser>( new ApplicationDbContext(entityConnectionString.ProviderConnectionString))); }
fuente