Is it possible to add columns to the AspNetUserLogins
table, or subclass the IdentityUserLogin
class, such that the Identity Framework will use that class properly?
相关问题
- Entity Framework Code First Migration
- Entity Framework throws exception - Network Relate
- Slow loading first page - ASP.NET MVC
- query and create objects with a one to many relati
- Entity Framework override default property convent
相关文章
-
EF6 DbSet
returns null in Moq - Entity Framework 4.3.1 failing to create (/open) a
- EF6 code first: How to load DbCompiledModel from E
- Why do I need a ToList() to avoid disposed context
- Code-First Add-Migration keeps adding the same col
- EF Codefirst validate unique property?
- EF Core 'another instance is already being tra
- Add XML documentation / comments to properties/fie
This is an answer but I'm sure it's not going to end up the best one:
It can be done, but it's ugly.
First, you'll want to make a class of all the generics you're about to use, just to make your life easier. Those are:
(The above superclasses can be found in
Microsoft.AspNet.Identity.EntityFramework
).This is going to make the following generic definitions shorter, and harder to get into a place where they won't compile due to clerical errors.
While you're here may as well add these to the DbContext, which normally does not leave them available to you:
Now, here comes the crazy:
And, Visitor is going to need its own adjustment to match this declaration:
That satisfies the Models (which btw, are best to have in their own Project for Migrations performance reasons). But, you've still got all the Identity/OWIN stuff to deal with.
By default you're provided with an ApplicationUserManager that involves a UserStore. It normally inherits from UserManager, but that's going to be too restrictive now - you need to slightly expand it:
I warned you about crazy. SignInManager:
That should get you through most of the dirty work. Not easy. But, having done that, you've got a working implementation where you can add extra fields to the Logins table! You can now extend the OWIN Auth stuff to provide events, and listen for the creation of new Logins. You can then respond to those by adding that extra info.
In our case, the goal was to have multiple Logins from multiple OpenId/OAuth Providers (Google, Facebook, etc) across multiple email addresses, on a single User/Visitor account. The framework does support that, but, it doesn't make a record of what Email is associated with what Login row, which is important when merging more Logins with a given account.
There's more you'll need to do to get the whole thing working, but it should be relatively obvious from the above starting point - with one exception, which I'll point out here.
By migrating from
UserManager<TVisitor>
toUserManager<TVisitor, string>
, you quietly lose the ID-generation functionality built-in to the former. You'll need to emulate it yourself. As another gotcha, along the way you'll most likely implementVisitor
asIUser<string>
. Doing so will prevent you from setting the Id property, because it's read-only (no setter). You can avoid that with a second interface:With that in place you can set Id safely (even in an abstracted class):
Remember to do same for CreateAsync(Visitor user, string password). Otherwise created users explode with
DbEntityValidationException
complaining Id is a required field.