Identity的自定义数据库表

时间:2015-12-21 16:38:20

标签: c# asp.net entity-framework asp.net-identity-2

我正在尝试为身份验证创建自定义表,但无论我多次尝试重新创建Identity表,我都会收到此错误:

  

实体类型' BBRoleType'和' UserRoleType'不能共享表' UserRoleTypes'因为它们不在同一类型层次结构中,或者没有有效的一对一外键关系,并且它们之间具有匹配的主键。

这是我在数据库中的用户表:

User tables

并导出为SQL:

/****** Object:  Table [dbo].[User]    Script Date: 21/12/2015 18:42:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[User](
    [Id] [uniqueidentifier] NOT NULL,
    [Email] [nvarchar](255) NOT NULL,
    [IsConfirmed] [bit] NOT NULL,
    [PasswordHash] [nvarchar](500) NULL,
    [SecurityStamp] [nvarchar](255) NULL,
    [UserName] [nvarchar](255) NOT NULL,
    [CreateDate] [datetime] NOT NULL,
    [LastOnlineDate] [datetime] NOT NULL,
    [BirthDate] [datetime] NULL,
    [FacebookAccessToken] [nvarchar](max) NOT NULL,
    [FacebookName] [nvarchar](500) NOT NULL,
    [FacebookId] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_User] 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] TEXTIMAGE_ON [PRIMARY]

GO
/****** Object:  Table [dbo].[UserClaim]    Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserClaim](
    [Id] [bigint] NOT NULL,
    [UserId] [uniqueidentifier] NOT NULL,
    [ClaimValue] [nvarchar](max) NOT NULL,
    [ClaimType] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_UserClaim] 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] TEXTIMAGE_ON [PRIMARY]

GO
/****** Object:  Table [dbo].[UserLogin]    Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserLogin](
    [UserId] [uniqueidentifier] NOT NULL,
    [ProviderKey] [nvarchar](max) NOT NULL,
    [LoginProvider] [nvarchar](max) NOT NULL,
    [UserLoginId] [uniqueidentifier] NOT NULL,
 CONSTRAINT [PK_UserLogin] PRIMARY KEY CLUSTERED 
(
    [UserLoginId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
/****** Object:  Table [dbo].[UserRole]    Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserRole](
    [RoleId] [uniqueidentifier] NOT NULL,
    [UserId] [uniqueidentifier] NOT NULL
) ON [PRIMARY]

GO
/****** Object:  Table [dbo].[UserRoleType]    Script Date: 21/12/2015 18:42:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserRoleType](
    [Id] [uniqueidentifier] NOT NULL,
    [Name] [nvarchar](255) NOT NULL,
 CONSTRAINT [PK_UserRoleType] 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
ALTER TABLE [dbo].[User] ADD  CONSTRAINT [DF_User_IsConfirmed]  DEFAULT ((0)) FOR [IsConfirmed]
GO
ALTER TABLE [dbo].[UserLogin] ADD  CONSTRAINT [DF_UserLogin_UserLoginId]  DEFAULT (newid()) FOR [UserLoginId]
GO
ALTER TABLE [dbo].[UserRoleType] ADD  CONSTRAINT [DF_UserRoleType_Id]  DEFAULT (newid()) FOR [Id]
GO
ALTER TABLE [dbo].[UserClaim]  WITH CHECK ADD  CONSTRAINT [FK_UserClaim_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
GO
ALTER TABLE [dbo].[UserClaim] CHECK CONSTRAINT [FK_UserClaim_User]
GO
ALTER TABLE [dbo].[UserLogin]  WITH CHECK ADD  CONSTRAINT [FK_UserLogin_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
GO
ALTER TABLE [dbo].[UserLogin] CHECK CONSTRAINT [FK_UserLogin_User]
GO
ALTER TABLE [dbo].[UserRole]  WITH CHECK ADD  CONSTRAINT [FK_UserRole_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
GO
ALTER TABLE [dbo].[UserRole] CHECK CONSTRAINT [FK_UserRole_User]
GO
ALTER TABLE [dbo].[UserRole]  WITH CHECK ADD  CONSTRAINT [FK_UserRole_UserRoleTyp] FOREIGN KEY([RoleId])
REFERENCES [dbo].[UserRoleType] ([Id])
GO
ALTER TABLE [dbo].[UserRole] CHECK CONSTRAINT [FK_UserRole_UserRoleTyp]
GO

创建表后,我为数据库添加了ADO.NET数据实体模型。

我创建了这些类来映射到自定义Identity类:

public class BBUserLogin : IdentityUserLogin<Guid> { }
public class BBUserRole : IdentityUserRole<Guid> { }

public class BBRoleType : IdentityRole<Guid,BBUserRole> { }
public class BBUserClaim : IdentityUserClaim<Guid> { }

public class BBUser : IdentityUser<Guid, BBUserLogin, BBUserRole, BBUserClaim>
{
    public DateTime CreateDate { get; set; }
    public DateTime LastOnlineDate { get; set; }
    public DateTime? BirthDate { get; set; }
    public string FacebookAccessToken { get; set; }
    public string FacebookName { get; set; }
    public string FacebookId { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<BBUser, Guid> manager)
    { 
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        userIdentity.AddClaim(new Claim(TCCustomClaimTypes.FirstName, this.FacebookName.SubstringUpToFirst(' ')));
        return userIdentity;
    }
}

然后设置我的DbContext:

public class ApplicationDbContext : IdentityDbContext<BBUser, BBRoleType, Guid, BBUserLogin, BBUserRole, BBUserClaim>
{
    public ApplicationDbContext() : base("MyIdentityConnection")
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.HasDefaultSchema("dbo");

        modelBuilder.Entity<BBUser>().ToTable("User");
        modelBuilder.Entity<BBUserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<BBUserLogin>().ToTable("UserLogin");
        modelBuilder.Entity<BBUserRole>().ToTable("UserRole");
        modelBuilder.Entity<BBRoleType>().ToTable("UserRoleType");

        modelBuilder.Entity<BBUser>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<BBUserClaim>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<BBRoleType>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }

不是我认为我很重要,但我在{I}尽可能地使用Guid / [uniqueidentifier](使用通用TKey的地方)。 IdentityUserClaim不允许更改Id类型,因此我使用bigint。不是我认为这很重要: - )

我一直在用这个问题把头撞到墙上,但是我无法弄清楚我做错了什么。

1 个答案:

答案 0 :(得分:0)

在我看来,密钥名称Id,Id,UserId和RoleId需要具有正确的命名。你可以更改密钥&#39; Id&#39;到UserId&#39;关于用户&#39;表?删除UserClaim表上的Id键。改变&#39; Id&#39;在UserRoleType表上的RoleId。

我认为这会解决您的问题。