整合&在EF中扩展.NET身份类(代码优先)

时间:2016-04-22 21:20:42

标签: c# asp.net-mvc entity-framework asp.net-mvc-4 asp.net-identity-3

我正在开始一个全新的.NET MVC项目,使用代码优先于EF 6和.NET 4.5。我也想使用Identity框架,并在我的项目的上下文配置中扩展Identity基类。 (不确定我说的都是正确的......我是一位经验丰富的C#/ .NET开发人员,对MVC,EF和Identity来说有点新鲜。)

我的问题:出了点问题。在尝试生成新迁移时,我收到错误:

POST.Data.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.
POST.Data.Models.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.

好的,我的项目中有两个上下文,一个用于Identity类,另一个用于其他所有内容。相同的数据库,任何一个上下文都没有引用另一个上下文中的任何内容。我这样定义了实体:

public class ApplicationUser : IdentityUser { }
public class ApplicationRole : IdentityRole { }
public class ApplicationUserRole : IdentityUserRole { }
public class ApplicationUserClaim : IdentityUserClaim { }
public class ApplicationUserLogin : IdentityUserLogin { }

然后,我有一个这样的上下文类:

public partial class IdentityContext : IdentityDbContext
{
    public IdentityContext() : base() { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(ul => ul.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(ur => new { ur.RoleId, ur.UserId });
    }

    public DbSet<ApplicationUser> ApplicationUsers { get; set; }
    public DbSet<ApplicationUserClaim> ApplicationUserClaims { get; set; }
    public DbSet<ApplicationUserLogin> ApplicationUserLogins { get; set; }
    public DbSet<ApplicationRole> ApplicationRoles { get; set; }
    public DbSet<ApplicationUserRole> ApplicationUserRoles { get; set; }
}

不确定它是否重要,但我的配置事情看起来像这样:

internal sealed class Configuration : DbMigrationsConfiguration<POST.Data.Models.Context>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"ContextMigrations";
    }

    protected override void Seed(POST.Data.Models.Context context) {}
}

这将构建,但我无法在没有这些错误的情况下生成迁移,并且凭借我对所有细节的有限知识和理解,我感到困惑。

2 个答案:

答案 0 :(得分:2)

您可以尝试使用属性Key设置实体密钥。像这样:

using System.ComponentModel.DataAnnotations;

namespace YourCompany.YourProject.Models
{
    public class ApplicationUser : IdentityUser
    {
        [Key]
        public string UserId { get; set; }
    }

    public class ApplicationRole : IdentityRole
    {
        [Key]
        public string Id { get; set; }
    }

    public class ApplicationUserRole : IdentityUserRole
    {
        [Key]
        public string UserId { get; set; }

        [Key]
        public string RoleId { get; set; }
    }

    public class ApplicationUserClaim : IdentityUserClaim { }

    public class ApplicationUserLogin : IdentityUserLogin { }
}

我希望它可以帮助你,如果确实如此,请将其标记为答案;)

答案 1 :(得分:2)

由于您没有为用户,角色等扩展任何身份实体,因此我不打算创建您自己的身份子类(ApplicationUser,ApplicationRole等)。您也不需要在上下文中定义任何与身份相关的DbSet,因为它们会自动从IdentityDbContext继承。但是,如果您想保留您的身份子类,您的DbContext应该从通用IdentityDbContext继承,因为这允许您定义自定义身份实体:

public class IdentityContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
   // Define other non-identity related dbsets
}

这将确保您的DbContext自动拥有所有相关的DbSet属性,而不必显式定义它们,因为它们是从通用IdentityDbContext&lt;&gt;继承而来的。类。

您也不需要在OnModelCreating中为任何标识内容定义任何迁移或流畅的api配置,因为您没有向标识实体添加任何内容(例如,其他ApplicationUser属性)。初始化DbContext / EF时,将自动创建默认标识表。