How to configure the Entity Framework model for Identity Framework to work with an existing database?

I am migrating my old site from PHP to C # MVC. I want to use the Microsoft Identity setting as it looks pretty neat.

I have already configured my solution using the database entity database. I have the necessary tables (Users, UserRoles, UserLogins, UserClaims) with all the foreign key settings.

I looked at several ways to configure IdentityUser , those that used MySqlDatabase and code before, but I'm not sure how to implement my IdentityUser when I already have the database installed, including the existing Users table.

I want my IdentityUser manipulate my Users using the Entity Framework classes that I have already created. Is there a way to make my User model in EF derived from IdentityUser and match my existing database?

One thing I'm struggling with is that my database does not use the string value as the primary key, it uses an auto-increment int .

I currently have the following class:

 // Copyright (c) KriaSoft, LLC. All rights reserved. See LICENSE.txt in the project root for license information. namespace KriaSoft.AspNet.Identity.EntityFramework { using Microsoft.AspNet.Identity; using System; public partial class IdentityUser : IUser<int> { /// <summary> /// Default constructor /// </summary> public IdentityUser() { Id = Guid.NewGuid().ToString(); } /// <summary> /// Constructor that takes user name as argument /// </summary> /// <param name="userName"></param> public IdentityUser(string userName) : this() { UserName = userName; } /// <summary> /// User ID /// </summary> public string Id { get; set; } /// <summary> /// User name /// </summary> public string UserName { get; set; } /// <summary> /// Email /// </summary> public virtual string Email { get; set; } /// <summary> /// True if the email is confirmed, default is false /// </summary> public virtual bool EmailConfirmed { get; set; } /// <summary> /// The salted/hashed form of the user password /// </summary> public virtual string PasswordHash { get; set; } /// <summary> /// A random value that should change whenever a users credentials have changed (password changed, login removed) /// </summary> public virtual string SecurityStamp { get; set; } /// <summary> /// PhoneNumber for the user /// </summary> public virtual string PhoneNumber { get; set; } /// <summary> /// True if the phone number is confirmed, default is false /// </summary> public virtual bool PhoneNumberConfirmed { get; set; } /// <summary> /// Is two factor enabled for the user /// </summary> public virtual bool TwoFactorEnabled { get; set; } /// <summary> /// DateTime in UTC when lockout ends, any time in the past is considered not locked out. /// </summary> public virtual DateTime? LockoutEndDateUtc { get; set; } /// <summary> /// Is lockout enabled for this user /// </summary> public virtual bool LockoutEnabled { get; set; } /// <summary> /// Used to record failures for the purposes of lockout /// </summary> public virtual int AccessFailedCount { get; set; } } } 

Of course, my Users object in my Entity Framework database context already has all of these properties, so it seems like they are a little pointless if they are listed there, as well as my context ... I'm really not sure: (.

I think my question is: how to use my existing User framework structure (database first) as my IdentityUser for Identity Asp.net?

+6
source share
1 answer

Now I am much more familiar with this.

The easiest way to get this to work, either first with code or with a database, is to modify the existing database so that it has at least the minimum database schema (tables, columns and foreign keys) that the ASP.NET Identity Framework uses.

You can see the minimal circuit in the image below:

Minimum Identity Framework Schema

Although it does not have column types, it is still useful to see it. You can get the exact schema from the SQL database database template specified on this page .

I am sure that you can avoid the need to bind the existing database to this scheme by creating some kind of mappings either inside your code (code first) or using the EF tools (database first) to map from the column name to another name inside your code ... but I have not tried it.

I created most of the tables from scratch, except for the User table, where I changed the original Username column to Username (case correction) to map and add additional columns that do not already exist.

First code

Once you have the database in place and you know that the schema is correct, you might want to use the reverse-engineer code first function for Visual Studio to raise your EF classes for you. This way, your new EF classes will exactly match your table layouts. Otherwise, you will have to code-copy all your models with all the mappings.

Once you have the EF classes, you must inherit them from different classes from the Identity Framework. Since you do this first as code, you can add inheritance to EF classes without fear that they will be overwritten (as opposed to a database).

 public class User : IdentityUser<int, UserLogin, UserRole, UserClaim> { // Any additional columns from your existing users table will appear here. } public class Role : IdentityRole<int, UserRole> { } public class UserClaim : IdentityUserClaim<int> { } public class UserLogin : IdentityUserLogin<int> { } public class UserRole : IdentityUserRole<int> { } 

Note the int specified in each, this indicates the type of the primary key of the user table. This is the default string, but my Id value in my existing database is an int that automatically increments.

Database first

When you use the EF database, firstly, you don’t have the luxury of adding the inheritance of Identity Framework classes directly to automatically generated classes. This is because they are overwritten every time you make changes to the model using the Visual Studio Entity Framework tools.

However, the created classes are automatically generated - these are all partial classes, so this can be achieved by creating a new file with the definition of partial classes that will not be overwritten. They must be in the same namespace and exactly the same name.

So, for example, it could be a class generated by EF:

 namespace Dal { public partial class User { // This class is auto generated by using EF database-first // We can't edit this class to add the inheritance, // because it will be overwritten every time // we update our model using the database-first tools } } 

And this is the model we can create to add our inheritance:

 // same namespace as existing class namespace Dal { // Same name as existing class public partial class User : IdentityUser<int, UserLogin, UserRole, UserClaim> { // This can probably be left blank } } 

So, you would do this for each of the classes required for the ASP.NET Identity Framework:

 public partial class User : IdentityUser<int, UserLogin, UserRole, UserClaim> { // Any additional columns from your existing users table will appear here. } public partial class Role : IdentityRole<int, UserRole> { } public partial class UserClaim : IdentityUserClaim<int> { } public partial class UserLogin : IdentityUserLogin<int> { } public partial class UserRole : IdentityUserRole<int> { } 
+5
source

Source: https://habr.com/ru/post/974617/


All Articles