One question that some students ask me is: How can I implement the Identity system when I already have a database created?
Normally, in my courses, I use Code First, that is, a technique from which I generate my database from C# code. However, another way to proceed is to start with a database and generate the corresponding C# code. In this second case, how can we set up Identity to handle a user system?
I’m going to do this post using: ASP.NET Core 5 and Entity Framework Core 5. Although I imagine that almost everything we do should work for other versions of these technologies.
As we have seen in the past, there are 2 path for working with Database first in EF Core:
- Activate migrations after generating the C# models
- Update models and DbContext without migrations
I’m going to show you how to configure Identity in any of the paths.
Whichever path you use, you must install this package: Microsoft.AspNetCore.Identity.EntityFrameworkCore
Path 1 – Activate migrations after generating the C# models
The idea of this path is that even though you started with a database, you want to migrate to Code First after generating the models and DbContext in C#.
In which case, you must do what is indicated in part of path 1 of this blog post to migrate from database first to code first.
After having done that, you must:
- Go to the DbContext and inherit from IdentityDbContext.
- In this same class, in the OnModelCreating method, add:
- Then add a migration and push the changes to the database.
That’s it! You now have the Identity tables in your database. To configure Identity we use the steps defined in the “Common Configuration” section below.
Path 2 – Adding the Identity tables without activating migrations
What if you don’t want to activate migrations, but you want to have your Identity tables? Well, you must proceed as follows.
First of all you need to have already made your Scaffold-DbContext, and have your DbContext generated from your database.
From here, I see two options:
- That you take the generated DbContext, and inherit from IdentityDbContext
- That you create a new DbContext, and inherit from IdentityDbContext
Both options are valid. The first is the simplest, and it is where we are going to start.
Here the idea is to go to the generated DbContext and inherit from IdentityDbContext. Then add this code in the first line of the OnModelCreating:
Now, we are going to generate the Identity tables in the database. For that we can run the following script in our database: https://gist.github.com/gavilanch/a5decf3dbc3a106c738860d3d52b1428
With this, we have the Identity tables in our database.
However, this solution has an annoying problem. If we try to rebuild the DbContext from the database, the models of the Identity tables will also be generated. This is not ideal, because such models already exist in our project (but EF Core doesn’t know that).
A possible solution to the above is to keep clearing those models when generating the DbContext.
Another possible solution is to ignore the Identity tables, only generating the ones you need: Either you indicate the tables when scaffolding, or you use a separate schema for the Identity tables.
Finally, another option you have is to use a second DbContext.
Here the idea is to have a DbContext which will have the Identity configuration. That way, you don’t have to edit the DbContext generated by the Scaffold, nor do you have to be careful not to generate the Identity tables when performing the Scaffold.
The downside of doing it this way is the difficulty of making a join between one of your tables and the Identity tables.
For this, what you must do is create a new class that inherits from IdentityDbContext, and use that class to configure Identity, ignoring the DbContext generated by the Scaffold.
There are several ways to configure Identity. One of them is to go to the Startup class, and, in the ConfigureServices method you must put (in my case, my DbContext is called DemoIdentityDBFirstContext):
services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<DemoIdentityDBFirstContext>() .AddDefaultTokenProviders(); // Conenction string should be on a configuration provider services.AddDbContext<DemoIdentityDBFirstContext>(options => options.UseSqlServer("Data Source=.;Initial Catalog=DemoIden
With the previous configuration, you should be able to use Identity with the DbContext that inherits from IdentityDbContext. At least in my case I was able to do a test, and I created a user in an application that uses “Path 1” and another user in an application that uses “Path 2”.
If you want to learn more about ASP.NET Core, or some other technology, check out my Udemy courses today. These links have a discount applied:
- Building Applications with Angular 11 and ASP.NET Core 5: https://www.udemy.com/course/building-applications-with-angular-and-aspnet-core/?couponCode=JUNE2021
- Programming in Blazor – ASP.NET Core 5: https://www.udemy.com/course/programming-in-blazor-aspnet-core/?couponCode=JUNE2021
- Building RESTful Web APIs with ASP.NET Core 3.1: https://www.udemy.com/course/building-restful-web-apis-with-aspnet-core/?couponCode=JUNE2021
- Introduction to Concurrency in C# – Async and Paralellism: https://www.udemy.com/course/introduction-to-concurrency-in-c-async-and-paralellism/?couponCode=JUNE2021