问题
I'm trying to customise ASP.NET Identity 3 so that it uses integer keys:
public class ApplicationUserLogin : IdentityUserLogin<int> { }
public class ApplicationUserRole : IdentityUserRole<int> { }
public class ApplicationUserClaim : IdentityUserClaim<int> { }
public sealed class ApplicationRole : IdentityRole<int>
{
public ApplicationRole() { }
public ApplicationRole(string name) { Name = name; }
}
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, int>
{
public ApplicationUserStore(ApplicationDbContext context) : base(context) { }
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, ApplicationDbContext, int>
{
public ApplicationRoleStore(ApplicationDbContext context) : base(context) { }
}
public class ApplicationUser : IdentityUser<int>
{
}
public sealed class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
{
private static bool _created;
public ApplicationDbContext()
{
// Create the database and schema if it doesn't exist
if (!_created) {
Database.AsRelational().Create();
Database.AsRelational().CreateTables();
_created = true;
}
}
}
This compiles okay, but then throws a runtime error:
System.TypeLoadException
GenericArguments[0], 'TeacherPlanner.Models.ApplicationUser', on 'Microsoft.AspNet.Identity.EntityFramework.UserStore`4[TUser,TRole,TContext,TKey]' violates the constraint of type parameter 'TUser'.
The signature for UserStore
is:
public class UserStore<TUser, TRole, TContext, TKey>
where TUser : Microsoft.AspNet.Identity.EntityFramework.IdentityUser<TKey>
where TRole : Microsoft.AspNet.Identity.EntityFramework.IdentityRole<TKey>
where TContext : Microsoft.Data.Entity.DbContext
where TKey : System.IEquatable<TKey>
ApplicationUser
is precisely an IdentityUser<int>
. Isn't this what it's looking for?
回答1:
Ran into this problem. It was crashing on the startup.cs file. changed
services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
to
services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext,int>()
.AddDefaultTokenProviders();
declaring the key type seemed to get past the crash
回答2:
Ran into this problem as well. I had to add IdentityRole key type also, because it was still throwing the same error.
services.AddIdentity<ApplicationUser, IdentityRole<int>>()
.AddEntityFrameworkStores<ApplicationDbContext,int>()
.AddDefaultTokenProviders();
回答3:
Note for EF Core Users
Just to add to the above, if you are using .Net core 3.0 (not sure about earlier versions), there is no longer a AddEntityFrameworkStores<TContext,TKey>
method.
Instead there is a generic variant of IdentityDbContext
so instead you derive your DbContext from IdentityDbContext<TUser,TRole,TKey>
e.g. in my case
class ApplicationUser : IdentityUser<int> {...}
class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<int>, int> {...}
then in your startup you can use services.AddDefaultIdentity<ApplicationUser>
cribbed from the last comment in https://github.com/aspnet/Identity/issues/1082
来源:https://stackoverflow.com/questions/30018109/why-does-this-violate-the-type-constraint