使用ApplicationUser创建数据库时,MVC5实体框架代码第一个错误



真的很感激如何在MVC5中使用我自己的自定义类中的ApplicationUser的一点指导。

简单的模型,使用脚手架创建控制器和视图,为Internet Application模板中的默认ApplicationUser (IdentityUser)创建DbContext。我想使用ApplicationUser用当时登录者的详细信息标记事务。

当实体框架试图DropAndRecreateAlways

时,我得到两个数据库错误之一

首先是我的班级:

public class Example
{
    public int ID { get; set; }
    [Required]
    public string Description { get; set; }
    [Required]
    public double Amount { get; set; }
    [Required]
    public virtual ApplicationUser CreatedBy {get; set;}
    [Required]
    public virtual ApplicationUser ModifiedBy { get; set; }
}

当实体框架试图创建数据库时我得到的错误是:

  1. {"在模型生成过程中检测到一个或多个验证错误:rnr nmvapplication1 . models . "IdentityUserLogin:: EntityType 'IdentityUserLogin'没有定义密钥。定义这个EntityType的键。IdentityUserRole:: EntityType 'IdentityUserRole'没有定义键。定义这个EntityType的键。rnIdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins'基于类型'IdentityUserLogin',没有定义密钥。rnIdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles'是基于类型'IdentityUserRole',没有定义键。rn"}

  2. 由于级联删除导致的引用完整性(我可以覆盖DbContext来删除级联删除)

实现这一目标的最佳方法是什么?

你的问题是你忘记打电话了

base.OnModelCreating(modelBuilder);

在你的方法上,因为就像你说的ApplicationDbContext是默认从IdentityDbContext继承创建的。呼叫基数。OnModelCreating,让你的基类如IdentityDbContext,生成所有你需要的。

但是如果你仍然想使用流畅的API,为这两个实体创建键的正确方法是

modelBuilder.Entity<IdentityUserLogin>().HasKey(t => new { t.UserId, t.ProviderKey, t.LoginProvider });
modelBuilder.Entity<IdentityUserRole>().HasKey(t => new { t.RoleId, t.UserId });

如果不这样做,调用UserManager的AddToRole(userid, rolename)方法将抛出一个异常,需要您添加的额外键,并带有消息"字段userid或RoleId是必需的"。

我建议您用[Key]属性注释您的ID。目前EF找不到表Example的主键基于你发布的第一个错误。

同样,如果您想在将来延迟加载CreatedByModifiedBy,您还需要提及Id,即使这现在不是一个错误。

除此之外,还从IdentityUser类继承ApplicationUser类,从IdentityDbContext类继承DbContext类。

清理项目,重新构建它,看看是否发生任何错误。这样解决起来就容易多了

它正在为您的实体寻找[Key]注释。看起来你缺少一个IdentityUserLoginIdentityUserRole

public class Person
{
    [Key] // <--- this needs to be identified here or in the DbContext you setup
    public Guid ID { get; set; }
}

两个建议:

1 -确保你的dbcontext从IdentityDbContext派生。

2 -基于你的模型,你有用户和你的其他实体之间的关系。您的dbcontext DBSet语句看起来如何?您为您的用户准备了数据库吗?(这意味着您正在假设管理用户而不是IdentityFramework)。如果您没有为您的用户设置DBSet,那么我同意Ashish的说法,Identity实体的上下文可能与您的其他实体的上下文不同,这将产生问题。

如果你能张贴你的上下文类的基本知识,我们可能能够告诉更多

我已经决定发布一个有效的答案,但是我仍然不相信这是最干净的答案,并希望听到是否有人有更好的方法来做到这一点。

我要做到这一点的答案是在ApplicationDbContext: IdentityDbContext中覆盖OnModelCreating(),并使用Fluent API将IdentityUserLoginIdentityUserRole的属性标记为[Key]

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Entity<IdentityUserLogin>().HasKey(t => t.UserId);
        modelBuilder.Entity<IdentityUserRole>().HasKey(t => t.UserId);
    }

我不认为这是一个很好的解决方案,因为EF Code First现在在我的IdentityUserLoginIdentityUserRole表,UserIdUser_Id中创建了两列。

现在就可以了。

相关内容

  • 没有找到相关文章

最新更新