How to set up the Entity Framework model for Identity Framework to work against an existing database?
I am now a lot more familiar with this.
The most straightforward way to get this to work either code-first or database-first, is to change your existing database so that it has at least the minimum database schema (tables, columns and foreign keys) that is used by ASP.NET Identity Framework.
You can see the minimum schema in the image below:
Although it doesn't have column types, it's still useful to see. You can get the precise schema from the SQL Database Project template listed on this page.
I'm sure it's possible to avoid having to make your existing database adhere to this schema by creating some kind of mappings either within your code (code-first) or using the EF tools (database-first) to map from the column name to another name within your code... but I haven't tried it.
I created most of the tables from scratch, other than the User
table, where I changed my original Username
column to the name UserName
(case correction) to match and added the additional columns that didn't already exist.
Code First
Once you have the database in place and you know that the schema is correct, then you may want to consider using the reverse-engineer code first
feature of Visual Studio to scaffold your EF classes for you. This way your new EF classes will match your table layouts precisely. Otherwise, you'll have to code all of your models yourself with all of the mappings.
Once you have the EF classes in place, you should make them inherit from different classes from Identity Framework. As you're doing this as code first, you can add the inheritance to the EF classes without any fear of them being overwritten (unlike with database first).
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>
{
}
Notice the int
specified in each, this specifies the primary key type of the User table. This is, by default, a string, but my Id
value in my existing database is an int
that auto-increments.
Database First
When you're using EF database-first, you don't have the luxury of adding the inheritance of the Identity Framework classes directly to the automatically generated classes. This is because they are overwritten every time you make a change to the model using the Entity Framework Visual Studio tools.
However, the classes that are created are auto generated are all partial
classes, so it can be achieved by creating a new file with the definition of the partial classes that won't get overwritten. They must be in the same namespace and exactly the same name.
So for example, this might be the 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 that we can create to add our inheritance to:
// 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 by 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>
{
}