在将 OnModelCreating 与 ApplicationDbContext 一起使用时解决“未定义键”错误?

Posted

技术标签:

【中文标题】在将 OnModelCreating 与 ApplicationDbContext 一起使用时解决“未定义键”错误?【英文标题】:Resolving 'No key Defined' errors while using OnModelCreating with ApplicationDbContext? 【发布时间】:2015-07-30 17:04:05 【问题描述】:

我一直在尝试为我的集合类型创建导航属性,我发现this example 有人使用 OnModelCreating 完成了它。我在我的 MVC 5 应用程序中试了一下,在尝试更新我的数据库时收到了这个错误:

在模型生成过程中检测到一个或多个验证错误:

BlogEngine.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' 没有定义键。定义此 EntityType 的键。 BlogEngine.Models.IdentityUserRole: : EntityType 'IdentityUserRole' 没有定义键。定义此 EntityType 的键。 IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' 是 基于没有定义键的类型“IdentityUserLogin”。 IdentityUserRoles:EntityType:EntitySet 'IdentityUserRoles' 是基于 在没有定义键的类型“IdentityUserRole”上。

如何解决这些“未定义键”错误?

我进行了一些搜索,发现this solution 解决了一位用户的问题,但他的需求与我的不同。对于我正在尝试做的事情,这些解决方案似乎相当复杂。

这是导致问题的代码:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        

        
        //public DbSet<Image> Images  get; set; 

        public static ApplicationDbContext Create()
        
            return new ApplicationDbContext();
        

        public DbSet<Post> Posts  get; set; 
        public DbSet<Image> Images  get; set; 
        public DbSet<Album> Albums  get; set; 
        public DbSet<Tag> Tags  get; set; 

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

            modelBuilder.Entity<Post>().
                 HasOptional(e => e.Tags).
                 WithMany().
                 HasForeignKey(m => m.Tags_Id);

            modelBuilder.Entity<Tag>().
                 HasOptional(e => e.Posts).
                 WithMany().
                 HasForeignKey(m => m.Posts_Id);
        

    

这是我的多对多关系模型:

Post.cs model on Gist

Tag.cs model on Gist


更新以显示 IdentityUser:

public class ApplicationUser : IdentityUser
    
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        
    

【问题讨论】:

您有任何名称为 IdentityUserLogin 的实体吗? 它内置在 MVC 5 模板中 你能检查一下有没有为此定义的键?因为错误表明该表没有键。 我不确定在哪里定义键,我假设如果代码带有来自微软的模板,它就会有它们。我想这可能是我问题解决方案的一部分...... 好的,请包括有问题的实体IdentittyUserLogin。 【参考方案1】:

您可能需要在OnModelCreating 中添加类似以下内容

modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new  r.RoleId, r.UserId );

另见:

Map tables using fluent api in asp.net MVC5 EF6? User in Entity type MVC5 EF6

【讨论】:

【参考方案2】:

我认为问题在于您已从 OnModelCreating 中删除了对 base 类的调用。尝试添加,如下所示

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

        //Your configuration goes here
    

【讨论】:

【参考方案3】:

我知道这是迟到的回应,这可能只适用于完成教程或学校项目的人!

对我来说,只需删除数据库、.mdf 和迁移文件夹即可修复它。现在,我不知道您是否正在使用迁移,但这对我有用。

我是新手,但我注意到 Identity 对密钥非常挑剔。删除迁移有助于解决我在项目中遇到的每个(godforsaken)迁移问题。

【讨论】:

不过,这不是什么好办法,不是吗?任何现实世界部署都需要迁移,删除数据库并重新开始不是一种选择。

以上是关于在将 OnModelCreating 与 ApplicationDbContext 一起使用时解决“未定义键”错误?的主要内容,如果未能解决你的问题,请参考以下文章

以下方法或属性 [ Entity Framework Core ] [ OnModelCreating ] 之间的调用不明确

在 EF7(核心)OnModelCreating 中使用自定义属性

在 OnModelCreating 中撤消 HasIndex

EF OnModelCreating

EF Core:检查 OnModelCreating 中是不是存在列以忽略属性

ef6 中的自动 CreatedAt 和 UpdatedAt 字段 OnModelCreating()