我有一个现有的数据库,该数据库已经有一个角色表,我正在尝试获取Identity以使用表中的现有角色,但我一直收到这个错误。
实体类型"ApplicationRole"one_answers"Role"不能共享表"角色",因为它们不在同一类型层次结构中或没有具有匹配主键的有效一对一外键关系他们之间。
我试图实现的表映射是
- AspNetUsers->User(ApplicationUser)
- AspNetRoles->角色(ApplicationRole)
- AspNetUserLogins->UserLogins(ApplicationUserLogin)
- AspNetUserRoles->RoleUser(ApplicationUserRole)
由于数据库正被其他应用程序使用,我无法首先使用代码。因此,我必须将我的脚本更改发送给DBA。
**现有SQL表**
/* Object: Table [dbo].[Role] */
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Role](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Description] [varchar](100) NOT NULL CONSTRAINT [DF_Role_Description] DEFAULT (''),
CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/* Object: Table [dbo].[RoleUser] */
CREATE TABLE [dbo].[RoleUser](
[UserID] [int] NOT NULL,
[RoleID] [int] NOT NULL,
CONSTRAINT [PK_AppUserRole] PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[RoleID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
/* Object: Table [dbo].[User] */
CREATE TABLE [dbo].[User](
[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[UserName] [dbo].[shortString] NOT NULL CONSTRAINT [DF_User_UserName] DEFAULT (''),
[FirstName] [dbo].[shortString] NULL CONSTRAINT [DF_User_FirstName] DEFAULT (''),
[LastName] [dbo].[shortString] NULL CONSTRAINT [DF_User_LastName] DEFAULT (''),
[Email] [dbo].[longString] NULL CONSTRAINT [DF_User_Email] DEFAULT (''),
[Pager] [dbo].[smallString] NULL CONSTRAINT [DF_User_Pager] DEFAULT (''),
[IsActive] [bit] NOT NULL CONSTRAINT [DF_User_IsActive] DEFAULT ((1)),
[LastPasswordChange] [datetime] NULL,
[AccountLockedDate] [datetime] NULL,
[AccountLockedByComputerName] [dbo].[shortString] NULL,
[AccountLockedByUserName] [dbo].[shortString] NULL,
[LastActive] [datetime] NULL,
[PasswordHash] [nvarchar](max) NULL,
[SecurityStamp] [nvarchar](max) NULL,
[Discriminator] [nvarchar](max) NULL,
[EmailConfirmed] [bit] NULL,
[PhoneNumber] [nvarchar](50) NULL,
[PhoneNumberConfirmed] [bit] NULL,
[TwoFactorEnabled] [bit] NULL,
[LockoutEndDateUtc] [datetime] NULL,
[LockoutEnabled] [bit] NULL,
[AccessFailedCount] [int] NULL,
CONSTRAINT [PK_AppUser] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
数据库上下文
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Asp.net Identity
modelBuilder.Entity<ApplicationUser>().ToTable("User");
modelBuilder.Entity<ApplicationRole>().ToTable("Role");
modelBuilder.Entity<ApplicationUserClaim>().ToTable("UserClaims");
modelBuilder.Entity<ApplicationUserLogin>().ToTable("UserLogins");
modelBuilder.Entity<ApplicationUserRole>().ToTable("RoleUser");
}
身份类别
public class ApplicationUserLogin : IdentityUserLogin<int> { }
public class ApplicationUserClaim : IdentityUserClaim<int> { }
public class ApplicationUserRole : IdentityUserRole<int> { }
public class ApplicationRole : IdentityRole<int, ApplicationUserRole>, IRole<int>
{
public string Description { get; set; }
public ApplicationRole() : base() { }
public ApplicationRole(string name)
: this()
{
this.Name = name;
}
public ApplicationRole(string name, string description)
: this(name)
{
this.Description = description;
}
}
public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>, IUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
{
var userIdentity = await manager
.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
试图建立FK/PK关系,但没有运气。
如果我创建了一个新的ASP.NET MVC应用程序,并按照您的指示更改了标识内容,并创建了只包含您指定的表的数据库,然后我尝试登录,那么我会收到一个错误
列名"密码"无效。
这很有意义,因为表的定义中没有"密码"字段,但该字段是在实体中定义的。
然后我将OnModelCreating
方法从:更改为
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Asp.net Identity
modelBuilder.Entity<ApplicationUser>().ToTable("User");
modelBuilder.Entity<ApplicationRole>().ToTable("Role");
modelBuilder.Entity<ApplicationUserClaim>().ToTable("UserClaims");
modelBuilder.Entity<ApplicationUserLogin>().ToTable("UserLogins");
modelBuilder.Entity<ApplicationUserRole>().ToTable("RoleUser");
}
至:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Asp.net Identity
modelBuilder.Entity<ApplicationUser>().ToTable("User");
modelBuilder.Entity<ApplicationRole>().ToTable("Role");
modelBuilder.Entity<ApplicationUserClaim>().ToTable("Role");
modelBuilder.Entity<ApplicationUserLogin>().ToTable("UserLogins");
modelBuilder.Entity<ApplicationUserRole>().ToTable("RoleUser");
}
然后我得到错误:
实体类型"ApplicationUserClaim"one_answers"ApplicationRole"无法共享表">Role",因为它们不在同一类型层次结构中,或者没有有效的一对一外键关系(它们之间的主键匹配)。
注意我的错误是如何抱怨Role
表的,而您的错误是抱怨Roles
表的
因此,在考虑了所有这些之后,我有一些意见、建议和要求:
- 没有根本问题阻止您以您想要的方式使用ASP.NET Identity,因为我能够在新安装时根据您的需要对其进行设置,并克服了它抱怨实体类型共享表的问题
- 也许你的应用程序中还有其他实体存在冲突,这可能吗
- 数据库中是否同时有"角色"one_answers"角色"表?还是项目中的实体?你确定这是你得到的错误,使用这个确切的代码,你发布?正如我所说,奇怪的是,你错误地抱怨角色,而我错误地抱怨角色
- 你能提供一个关于这个问题的最简单的可验证的例子吗(https://stackoverflow.com/help/mcve)正如我所说,我无法从一个干净的MVC项目中重现这个问题
您需要告诉EF和Identity关于Role
和UserRole
之间的关系。
尝试添加以下内容:
public class ApplicationUserRole : IdentityUserRole<int>
{
public ApplicationUserRole()
: base()
{ }
//this is important
public virtual ApplicationRole Role { get; set; }
}
在您的OnModelCreating
上添加此行以建立关系:
modelBuilder.Entity<ApplicationUserRole>().HasRequired(ur => ur.Role).WithMany().HasForeignKey(ur => ur.RoleID);
此外,如果以上内容不能解决问题,请发布您的DbContext代码。