C# 手动为ASP.Net标识现有数据库编写脚本

C# 手动为ASP.Net标识现有数据库编写脚本,c#,asp.net,asp.net-identity,C#,Asp.net,Asp.net Identity,我有一个已经有角色表的现有数据库,我正在尝试获取标识以使用表中的现有角色,但我一直收到此错误 实体类型“ApplicationRole”和“Role”无法共享表 “角色”,因为它们不在同一类型层次结构中或没有 具有匹配主键的有效一对一外键关系 在他们之间 我试图实现的表映射是 AspNetUsers->User(应用程序用户) AspNetRoles->Role(应用程序角色) AspNetUserLogins->UserLogins(ApplicationUserLogin) AspNetU

我有一个已经有角色表的现有数据库,我正在尝试获取标识以使用表中的现有角色,但我一直收到此错误

实体类型“ApplicationRole”和“Role”无法共享表 “角色”,因为它们不在同一类型层次结构中或没有 具有匹配主键的有效一对一外键关系 在他们之间

我试图实现的表映射是

  • AspNetUsers->User(应用程序用户)
  • AspNetRoles->Role(应用程序角色)
  • 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");
        }
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//Asp.net标识
modelBuilder.Entity().ToTable(“用户”);
modelBuilder.Entity().ToTable(“角色”);
modelBuilder.Entity().ToTable(“用户声明”);
modelBuilder.Entity().ToTable(“用户登录”);
modelBuilder.Entity().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;
        }
    }
public类ApplicationUserLogin:IdentityUserLogin{}
公共类ApplicationUserClaim:IdentityUserClaim{}
公共类ApplicationUserRole:IdentityUserRole{}
公共类应用程序角色:IdentityRole、IRole
{
公共字符串说明{get;set;}
公共应用程序角色():基(){}
公共应用程序角色(字符串名称)
:此()
{
this.Name=Name;
}
公共应用程序角色(字符串名称、字符串描述)
:此(名称)
{
这个。描述=描述;
}
}
公共类应用程序用户:IdentityUser,IUser
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串密码{get;set;}
公共异步任务GenerateUserIdentityAsync(用户管理器)
{
var userIdentity=等待管理器
.CreateIdentityAsync(这是DefaultAuthenticationTypes.ApplicationOkie);
返回用户身份;
}
}

试图创建FK/PK关系,但运气不佳。

您需要告诉EF和Identity有关
角色
用户角色
之间的关系

尝试添加以下内容:

public class ApplicationUserRole : IdentityUserRole<int>
{
    public ApplicationUserRole()
        : base()
    { }
    //this is important
    public virtual ApplicationRole Role { get; set; }
}

此外,如果上述方法无法解决问题,请发布您的DbContext代码。

如果我创建了一个新的ASP.NET MVC应用程序,并按照您的指示更改了标识内容,创建了一个只包含您指定的表的数据库,并且我尝试登录,则会出现错误

列名“Password”无效

这很有意义,因为在表的定义中没有“Password”字段,但该字段是在实体中定义的

然后,我将模型创建上的
方法更改为:

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");
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//Asp.net标识
(modelBuilder.Entity)正如我所说,我无法从一个干净的MVC项目中重现这个问题

您真正想要做什么?di您需要ApplicationRole和Role共享同一个现有表?ApplicationRole只是扩展了我的IdentityRole以使用int而不是字符串。我只希望Identity使用Role表来管理角色。
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");
}