为什么这违反了类型参数"TUser"的约束? [英] Why this violates the constraint of type parameter 'TUser'?

查看:421
本文介绍了为什么这违反了类型参数"TUser"的约束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用以下内容自定义asp.net身份实体:

public class User : IdentityUser<string, UserClaim, UserRole, UserLogin>
public class UserClaim : IdentityUserClaim<string>
public class UserLogin : IdentityUserLogin<string>
public class UserRole : IdentityUserRole<string>
public class UserToken : IdentityUserToken<string>
public class Role : IdentityRole<string, UserRole, RoleClaim>
public class RoleClaim : IdentityRoleClaim<string>

然后我创建了一个DbContext类,如下所示

public class AppDbContext : IdentityDbContext<User, Role, string, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>

然后使用

配置它们

services
    .AddIdentity<User, Role>()
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

但是我也尝试过

.AddEntityFrameworkStores<AppDbContext, string>()

我在互联网上阅读了许多博客文章,例如 this ,但是其中大多数必须处理键的数据类型更改,例如intGuid.就我而言,我没有从string更改默认密钥数据类型.

在所有这些情况下,编译都可以,但运行时会引发错误

System.TypeLoadException GenericArguments [0],"MyIdentity.Entities.User",在 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`8 [TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken]' 违反类型参数'TUser'的约束.

在System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle句柄, IntPtr * pInst,int numGenericArgs,ObjectHandleOnStack类型) System.RuntimeTypeHandle.Instantiate(Type [] inst)在 System.RuntimeType.MakeGenericType(Type []实例化)

如果我像UserStore类, >此帖子

public class UserStore : UserStore<User, Role, AppDbContext, string, UserClaim, UserRole, UserLogin, UserToken>

出现编译错误,表明

CS0311类型'MyIdentity.Entities.Role'不能用作类型 通用类型或方法"UserStore"中的参数"TRole".没有来自的隐式引用转换 "MyIdentity.Entities.Role" 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>'

我做错了什么?

解决方案

  • 根据MSDN UserStore<TUser>的约束是TUser : IdentityUser.
  • 也根据MSDN IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>.
  • 根据您的声明,User : IdentityUser<string, UserClaim, UserRole, UserLogin>.

长名称很容易遗漏,因此我们将IdentityUser命名为D,将IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>命名为B.现在,以上内容可以重述为:

  • TUser : D(TUser必须是D的一种)
  • D : B(DB的一种)
  • User : B(根据需要,您的User通常是B的一种,但不是具体的D的一种)

I am trying to customize asp.net identity entities with the following ones:

public class User : IdentityUser<string, UserClaim, UserRole, UserLogin>
public class UserClaim : IdentityUserClaim<string>
public class UserLogin : IdentityUserLogin<string>
public class UserRole : IdentityUserRole<string>
public class UserToken : IdentityUserToken<string>
public class Role : IdentityRole<string, UserRole, RoleClaim>
public class RoleClaim : IdentityRoleClaim<string>

I have then created a DbContext class like the following

public class AppDbContext : IdentityDbContext<User, Role, string, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>

And then configure these with

services
    .AddIdentity<User, Role>()
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

but I have tried also with

.AddEntityFrameworkStores<AppDbContext, string>()

I have read many blog posts on the internet, like this for example, but most of them have to deal against a change of data type for the keys, like to int or Guid. In my case I am not changing the default key datatype from string.

I all these cases the compile is ok but it throws an error when running

System.TypeLoadException GenericArguments[0],'MyIdentity.Entities.User', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`8[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken]' violates the constraint of type parameter 'TUser'.

at System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type) at System.RuntimeTypeHandle.Instantiate(Type[] inst) at System.RuntimeType.MakeGenericType(Type[] instantiation)

If I add a customized UserStore class like explained in this post

public class UserStore : UserStore<User, Role, AppDbContext, string, UserClaim, UserRole, UserLogin, UserToken>

A compile error appear saying that

CS0311 The type 'MyIdentity.Entities.Role' cannot be used as type parameter 'TRole' in the generic type or method 'UserStore'. There is no implicit reference conversion from 'MyIdentity.Entities.Role' to 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>'

What I am doing wrong?

解决方案

  • According to MSDN, the constraint for UserStore<TUser> is TUser : IdentityUser.
  • Also according to MSDN, IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>.
  • According to your declarations, User : IdentityUser<string, UserClaim, UserRole, UserLogin>.

The long names make it easy to miss, so let's alias IdentityUser as D and IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> as B. Now the above can be restated as:

  • TUser : D (a TUser must be a kind of D)
  • D : B (D is a kind of B)
  • User : B (your User is a kind of B in general but not a kind of D specifically, as required)

这篇关于为什么这违反了类型参数"TUser"的约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆