Id quadro ASP.NET con EF Database First MVC5

È ansible utilizzare il nuovo Asp.net Identity con Database First ed EDMX? O solo con il codice prima?

Ecco cosa ho fatto:

1) Ho creato un nuovo progetto MVC5 e ho creato la nuova id quadro per creare le nuove tabelle Utente e Ruoli nel mio database.

2) Ho quindi aperto il mio file Database First EDMX e trascinato nella nuova tabella Identity Users poiché ho altre tabelle che si riferiscono ad esso.

3) Al momento del salvataggio di EDMX, il primo generatore POCO del database creerà automaticamente una class utente. Tuttavia, UserManager e RoleManager prevedono una class User ereditata dal nuovo spazio dei nomi Identity (Microsoft.AspNet.Identity.IUser), quindi l’utilizzo della class utente POCO non funzionerà.

    Immagino che una ansible soluzione sia quella di modificare le mie Classi di Generazione POCO affinché la mia class Utente venga ereditata da IUser?

    Oppure ASP.NET Identity è compatibile solo con Code First Design?

    ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++

    Aggiornamento: seguendo il suggerimento di Anders Abel di seguito, questo è quello che ho fatto. Funziona, ma mi chiedo se esiste una soluzione più elegante.

    1) Ho esteso la mia class User di quadro creando una class parziale all’interno dello stesso spazio dei nomi delle mie quadro generate automaticamente.

    namespace MVC5.DBFirst.Entity { public partial class AspNetUser : IdentityUser { } } 

    2) Ho cambiato il mio DataContext per ereditare da IdentityDBContext invece di DBContext. Si noti che ogni volta che si aggiorna EDMX e si rigenerano le classi DBContext ed Entity, è necessario reimpostarlo.

      public partial class MVC5Test_DBEntities : IdentityDbContext //DbContext 

    3) All’interno della class di quadro utente generata automaticamente, è necessario aggiungere la parola chiave override ai seguenti 4 campi o commentare questi campi poiché sono ereditati da IdentityUser (Passaggio 1). Si noti che ogni volta che si aggiorna EDMX e si rigenerano le classi DBContext ed Entity, è necessario reimpostarlo.

      override public string Id { get; set; } override public string UserName { get; set; } override public string PasswordHash { get; set; } override public string SecurityStamp { get; set; } 

    Dovrebbe essere ansible usare il sistema di identity framework con POCO e Database First, ma dovrai fare un paio di modifiche:

    1. Aggiorna il file .tt per la generazione POCO per rendere partial classi di quadro. Ciò ti consentirà di fornire un’implementazione aggiuntiva in un file separato.
    2. Effettua un’implementazione parziale della class User in un altro file
     partial User : IUser { } 

    Ciò renderà la class User implementare l’interfaccia giusta, senza toccare i file effettivamente generati (la modifica dei file generati è sempre una ctriggers idea).

    I miei passi sono molto simili ma volevo condividere.

    1) Crea un nuovo progetto MVC5

    2) Crea un nuovo Model.edmx. Anche se è un nuovo database e non ha tabelle.

    3) Modifica web.config e sostituisci questa connessione generata:

      

    con questa connessione:

      

    Successivamente, crea ed esegui l’applicazione. Registra un utente e quindi verranno create le tabelle.

    EDIT: Identity framework ASP.NET con EF Database First per MVC5 CodePlex Modello di progetto.


    Volevo utilizzare un database esistente e creare relazioni con ApplicationUser. Questo è il modo in cui l’ho fatto usando SQL Server ma la stessa idea probabilmente funzionerebbe con qualsiasi DB.

    1. Crea un progetto MVC
    2. Aprire il DB elencato sotto DefaultConnection in Web.config. Sarà chiamato (aspnet- [timestamp] o qualcosa di simile.)
    3. Script le tabelle del database.
    4. Inserire le tabelle con script nel database esistente in SQL Server Management Studio.
    5. Personalizza e aggiungi relazioni a ApplicationUser (se necessario).
    6. Crea nuovo progetto web> MVC> DB Primo progetto> Importa DB con EF … Escludendo le classi di id quadro che hai inserito.
    7. In IdentityModels.cs cambia ApplicationDbContext :base("DefaltConnection") per utilizzare DbContext del tuo progetto.

    Modifica: Asp.Net Identity Class Diagram inserisci la descrizione dell'immagine qui

    IdentityUser è inutile qui perché è l’object in codice utilizzato da UserStore per l’autenticazione. Dopo aver definito il mio object User , ho implementato una class parziale che implementa IUser che viene utilizzata dalla class UserManager . Volevo che il mio Id s fosse int invece di string, quindi restituisco solo il comando userString (). Allo stesso modo volevo n in Username per essere incapitalizzato.

     public partial class User : IUser { public string Id { get { return this.UserID.ToString(); } } public string UserName { get { return this.Username; } set { this.Username = value; } } } 

    Non hai affatto bisogno di IUser . È solo un’interfaccia utilizzata da UserManager . Pertanto, se si desidera definire un “IUser” diverso, è necessario riscrivere questa class per utilizzare la propria implementazione.

     public class UserManager : IDisposable where TUser: IUser 

    Ora scrivi il tuo UserStore che gestisce tutto lo storage di utenti, attestazioni, ruoli, ecc. Implementa le interfacce di tutto ciò che fa il primo UserStore e cambia where TUser : IdentityUser a where TUser : User dove “Utente” è il tuo object quadro

     public class MyUserStore : IUserLoginStore, IUserClaimStore, IUserRoleStore, IUserPasswordStore, IUserSecurityStampStore, IUserStore, IDisposable where TUser : User { private readonly MyAppEntities _context; public MyUserStore(MyAppEntities dbContext) { _context = dbContext; } //Interface definitions } 

    Ecco alcuni esempi su alcune delle implementazioni dell’interfaccia

     async Task IUserStore.CreateAsync(TUser user) { user.CreatedDate = DateTime.Now; _context.Users.Add(user); await _context.SaveChangesAsync(); } async Task IUserStore.DeleteAsync(TUser user) { _context.Users.Remove(user); await _context.SaveChangesAsync(); } 

    Usando il modello MVC 5, ho modificato AccountController per assomigliare a questo.

     public AccountController() : this(new UserManager(new MyUserStore(new MyAppEntities()))) { } 

    Ora l’accesso dovrebbe funzionare con le tue tabelle.

    Dai un’occhiata a questo progetto su GitHub: https://github.com/KriaSoft/AspNet.Identity

    Che include:

    • Modello di progetto del database SQL per ASP.NET Identity 2.0
    • Database di quadro primo database (s)
    • Codice sorgente e campioni

    inserisci la descrizione dell'immagine qui

    Vedere anche : Come creare il provider Database-First per l’id quadro ADO.NET

    Ho passato diverse ore a lavorare su questo e finalmente ho trovato una soluzione che ho condiviso sul mio blog qui . Fondamentalmente, devi fare tutto quanto detto nella risposta di puzz ma con una cosa aggiuntiva: assicurarti che Identity Framework abbia una specifica stringa di connessione SQL-Client sulla stringa di connessione di Entity Framework usata per le entity framework dell’applicazione.

    In breve, l’applicazione utilizzerà una stringa di connessione per Identity Framework e un’altra per le quadro dell’applicazione. Ogni stringa di connessione è di un tipo diverso. Leggi il mio post sul blog per un tutorial completo.

    Buona domanda.

    Sono più un database-prima persona. Il primo paradigma del codice mi sembra un po ‘sciocco, e le “migrazioni” sembrano troppo inclini agli errori.

    Volevo personalizzare lo schema di id quadro di Aspnet e non essere disturbato dalle migrazioni. Sono esperto di progetti di database di Visual Studio (sqlpackage, data-dude) e di come fa un buon lavoro nell’aggiornamento degli schemi.

    La mia soluzione semplicistica è:

    1) Creare un progetto di database che rispecchia lo schema di id quadro di Aspnet 2) utilizzare l’output di questo progetto (.dacpac) come risorsa di progetto 3) distribuire il .dacpac quando necessario

    Per MVC5, la modifica della class ApplicationDbContext sembra andare avanti …

    1) Implementare IDatabaseInitializer

    public class ApplicationDbContext : IdentityDbContext, IDatabaseInitializer { ... }

    2) Nel costruttore, segnala che questa class implementerà l’inizializzazione del database:

    Database.SetInitializer(this);

    3) Implementare InitializeDatabase :

    Qui, ho scelto di usare DacFX e distribuire il mio .dacpac

      void IDatabaseInitializer.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); } } } 

    Abbiamo un progetto DLL Entity Model in cui manteniamo la class del nostro modello. Manteniamo anche un progetto di database con tutti gli script di database. Il mio approccio era il seguente

    1) Crea il tuo progetto che ha EDMX usando prima il database

    2) Script le tabelle nel tuo db, ho usato VS2013 connesso a localDB (Data Connections) e ho copiato lo script nel progetto del database, aggiungo qualsiasi colonna personalizzata, ad es. BirthDate [DATE] not null

    3) Distribuire il database

    4) Aggiornare il progetto Modello (EDMX) Aggiungi al progetto Modello

    5) Aggiungi eventuali colonne personalizzate alla class dell’applicazione

     public class ApplicationUser : IdentityUser { public DateTime BirthDate { get; set; } } 

    Nel progetto MVC AccountController ha aggiunto quanto segue:

    Il provider di identity framework desidera che una stringa di connessione SQL funzioni, per mantenere solo una stringa di connessione per il database, estrarre la stringa del provider dalla stringa di connessione EF

     public AccountController() { var connection = ConfigurationManager.ConnectionStrings["Entities"]; var entityConnectionString = new EntityConnectionStringBuilder(connection.ConnectionString); UserManager = new UserManager( new UserStore( new ApplicationDbContext(entityConnectionString.ProviderConnectionString))); } 

    Ho scoperto che @ JoshYates1980 ha la risposta più semplice.

    Dopo una serie di prove ed errori ho fatto quello che Josh ha suggerito e ho sostituito la connectionString con la mia stringa di connessione DB generata. quello di cui ero inizialmente confuso era il seguente post:

    Come aggiungere ASP.NET MVC5 Identity Authentication al database esistente

    Dove la risposta accettata da @Win ha dichiarato di cambiare il nome della connessione ApplicationDbContext() . Questo è un po ‘vago se si utilizza Entity e un primo approccio Database / Model in cui la stringa di connessione al database viene generata e aggiunta al file Web.config .

    Il nome della connessione ApplicationDbContext() è mappato alla connessione predefinita nel file Web.config . Pertanto, il metodo di Josh funziona meglio, ma per rendere più leggibile ApplicationDbContext() suggerirei di cambiare il nome nel nome del tuo database come @Win originariamente pubblicato, assicurandoti di cambiare connectionString per “DefaultConnection” in Web.config e commentare include e / o remov include il database generato dall’ quadro.

    Esempi di codice: