在Identity 2中扩展IdentityUserRole的PrimaryKey

时间:2015-02-25 14:05:46

标签: c# ef-migrations asp.net-identity-2

是否可以通过附加列扩展ApplicationUserRole的主键?

默认情况下,有两列定义为主键:UserIdRoleId

这是默认实现

public partial class ApplicationUserRole : IdentityUserRole<string>
{
    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
}

public class IdentityUserRole<TKey>
{
    public IdentityUserRole();

    // Summary:
    //     RoleId for the role
    public virtual TKey RoleId { get; set; }
    //
    // Summary:
    //     UserId for the user that is in the role
    public virtual TKey UserId { get; set; }
}

并且db中的表看起来像

CREATE TABLE [dbo].[AspNetUserRoles](
    [UserId] [nvarchar](128) NOT NULL,
    [RoleId] [nvarchar](128) NOT NULL,
 CONSTRAINT [PK_dbo.AspNetUserRoles] 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) ON [PRIMARY]
) ON [PRIMARY]

但我需要更多! :) 我的意思是我希望我的模型看起来像

public partial class ApplicationUserRole : IdentityUserRole<string>
{

    public Guid ServiceId { get; set; }

    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
    public virtual Service Service { get; set; }

}

我无法理解如何使用数据注释或流畅的api以正确的方式执行此操作。我没试过就试过了两次。 似乎迁移引擎忽略该模型的任何主键更改。 至少当我添加注释或流畅的api方法时,迁移引擎会生成空的迁移脚本。

我刚刚添加了serviceId属性,我的表现在看起来像

CREATE TABLE [dbo].[AspNetUserRoles](
    [UserId] [nvarchar](128) NOT NULL,
    [RoleId] [nvarchar](128) NOT NULL,
    [ServiceId] [uniqueidentifier] NOT NULL,
 CONSTRAINT [PK_dbo.AspNetUserRoles] 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) ON [PRIMARY]
) ON [PRIMARY]

当我尝试通过注释或流畅的api应用密钥更改时 迁移脚本看起来像

public partial class rolesmigrate02 : DbMigration
{
    public override void Up()
    {
    }

    public override void Down()
    {
    }
}
流利的api:

modelBuilder.Entity<ApplicationUserRole>().HasKey(hk => new { hk.UserId, hk.RoleId, hk.ServiceId});

注释

public partial class ApplicationUserRole : IdentityUserRole<string>
{
    [Key, Column(Order = 0)]
    public override string UserId { get; set; }
    [Key, Column(Order = 1)]
    public override string RoleId { get; set; }
    [Key, Column(Order = 2)]
    public Guid ServiceId { get; set; }

    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
    public virtual Service Service { get; set; }
}

我可以在数据库中手动进行更改,但我怀疑是 我的错在哪里?为什么我不能通过代码首次迁移来扩展这个模型?

1 个答案:

答案 0 :(得分:2)

花了一些时间我发现了这篇文章Sam about identity 2 on StackOverflow

关键是base.OnModelCreating(modelBuilder)

如果我们想重新应用或修改预定义的身份2映射,我们应该在base.OnModelCreating之后进行。

如此流畅的api应该看起来像

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // usualy i put this line to the end of this method but it should be before
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ApplicationUserRole>().HasKey(hk => new { hk.UserId, hk.RoleId, hk.ServiceId});
    }