为什么这违反了类型约束?

21

我正在尝试自定义ASP.NET Identity 3,使其使用整数主键:

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;
    }
  }
}

这段代码可以编译通过,但是在运行时会抛出一个错误:

System.TypeLoadException

UserStore 的签名为:

'Microsoft.AspNet.Identity.EntityFramework.UserStore`4[TUser,TRole,TContext,TKey]'

但是,GenericArguments[0], 'TeacherPlanner.Models.ApplicationUser',违反了类型参数 'TUser' 的约束条件。

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 实际上是一个 IdentityUser<int>。这不就是它要找的吗?


1
你是否不小心在项目中声明了一个与IdentityUser同名的新类型?我有时会这样做,因为在CodeRush中选择“声明类型”而不是“添加使用语句”。 - James McLachlan
3个回答

45
我遇到了这个问题。它在 startup.cs 文件上崩溃了。 改变了。
services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext,int>()
                .AddDefaultTokenProviders();

声明密钥类型似乎能够避免崩溃


我曾担心我必须覆盖所有的身份类和方法,因为我的密钥很长,但是通过这个小修复,一切都可以正常工作。谢谢! - Atchitutchuk

9
我也遇到了这个问题。我不得不添加 IdentityRole 键类型,因为它仍然会抛出相同的错误。
        services.AddIdentity<ApplicationUser, IdentityRole<int>>()
            .AddEntityFrameworkStores<ApplicationDbContext,int>()
            .AddDefaultTokenProviders();

3

注意 EF Core 用户

补充一下上面的内容,如果您正在使用 .Net Core 3.0(之前的版本不确定),那么就没有 AddEntityFrameworkStores<TContext,TKey> 方法了。

相反地,现在有一个泛型的 IdentityDbContext 变种,您需要从 IdentityDbContext<TUser,TRole,TKey> 派生出您的 DbContext。

例如,在我的情况下:

class ApplicationUser : IdentityUser<int> {...}
class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<int>, int> {...}

然后在您的启动代码中,您可以使用services.AddDefaultIdentity<ApplicationUser>

引用自https://github.com/aspnet/Identity/issues/1082最后一条评论。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接