0

我从一个空的 asp.net core 2 项目开始,想向它添加功能,以便我可以学习所有部分。我在 Azure 中创建了一个要连接的数据库,并且我的项目中有一个 dbContext。我正在使用 ASP.NET Core 标识,并且已成功将表添加到应用程序中。我正在尝试对我的数据库上下文进行一些更改并将其推送到我的数据库中。这就是我所理解的,需要在 EF Core 中使用“代码优先”来完成。当我尝试在 PMC 中创建新迁移时,出现以下错误。我不知道这是什么意思。对此有什么想法吗?我该如何解决这个问题?

TIA

错误信息:

不能将表 'AspNetRoleClaims' 用于实体类型 'AspNetRoleClaims',因为它用于实体类型 'IdentityRoleClaim' 并且主键 {'Id'} 和主键 {'Id'} 之间没有关系。

我的数据库上下文的来源:

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace PooperApp.Models
{
    public partial class PoopTheWorldContext : Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
    {
        public virtual DbSet<AspNetRoleClaims> AspNetRoleClaims { get; set; }
        public virtual DbSet<AspNetRoles> AspNetRoles { get; set; }
        public virtual DbSet<AspNetUserClaims> AspNetUserClaims { get; set; }
        public virtual DbSet<AspNetUserLogins> AspNetUserLogins { get; set; }
        public virtual DbSet<AspNetUserRoles> AspNetUserRoles { get; set; }
        public virtual DbSet<AspNetUsers> AspNetUsers { get; set; }
        public virtual DbSet<AspNetUserTokens> AspNetUserTokens { get; set; }
        public virtual DbSet<Clean> Clean { get; set; }
        public virtual DbSet<Country> Country { get; set; }
        public virtual DbSet<PoopLocation> PoopLocation { get; set; }
        public virtual DbSet<Province> Province { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            if (!optionsBuilder.IsConfigured)
            {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
                optionsBuilder.UseSqlServer(@"......");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<AspNetRoleClaims>(entity =>
            {
                entity.HasKey(e => e.Id);
                entity.HasIndex(e => e.RoleId);

                entity.HasOne(d => d.Role)
                    .WithMany(p => p.AspNetRoleClaims)
                    .HasForeignKey(d => d.RoleId);
            });

            modelBuilder.Entity<AspNetRoles>(entity =>
            {
                entity.HasIndex(e => e.NormalizedName)
                    .HasName("RoleNameIndex")
                    .IsUnique()
                    .HasFilter("([NormalizedName] IS NOT NULL)");

                entity.Property(e => e.Id).ValueGeneratedNever();

                entity.Property(e => e.Ipaddress).HasColumnName("IPAddress");

                entity.Property(e => e.Name).HasMaxLength(256);

                entity.Property(e => e.NormalizedName).HasMaxLength(256);
            });

            modelBuilder.Entity<AspNetUserClaims>(entity =>
            {
                entity.HasIndex(e => e.UserId);

                entity.HasOne(d => d.User)
                    .WithMany(p => p.AspNetUserClaims)
                    .HasForeignKey(d => d.UserId);
            });

            modelBuilder.Entity<AspNetUserLogins>(entity =>
            {
                entity.HasKey(e => new { e.LoginProvider, e.ProviderKey });

                entity.HasIndex(e => e.UserId);

                entity.HasOne(d => d.User)
                    .WithMany(p => p.AspNetUserLogins)
                    .HasForeignKey(d => d.UserId);
            });

            modelBuilder.Entity<AspNetUserRoles>(entity =>
            {
                entity.HasKey(e => new { e.UserId, e.RoleId });

                entity.HasIndex(e => e.RoleId);

                entity.HasOne(d => d.Role)
                    .WithMany(p => p.AspNetUserRoles)
                    .HasForeignKey(d => d.RoleId);

                entity.HasOne(d => d.User)
                    .WithMany(p => p.AspNetUserRoles)
                    .HasForeignKey(d => d.UserId);
            });

            modelBuilder.Entity<AspNetUsers>(entity =>
            {
                entity.HasIndex(e => e.NormalizedEmail)
                    .HasName("EmailIndex");

                entity.HasIndex(e => e.NormalizedUserName)
                    .HasName("UserNameIndex")
                    .IsUnique()
                    .HasFilter("([NormalizedUserName] IS NOT NULL)");

                entity.Property(e => e.Id).ValueGeneratedNever();

                entity.Property(e => e.Email).HasMaxLength(256);

                entity.Property(e => e.NormalizedEmail).HasMaxLength(256);

                entity.Property(e => e.NormalizedUserName).HasMaxLength(256);

                entity.Property(e => e.UserName).HasMaxLength(256);
            });

            modelBuilder.Entity<AspNetUserTokens>(entity =>
            {
                entity.HasKey(e => new { e.UserId, e.LoginProvider, e.Name });

                entity.HasOne(d => d.User)
                    .WithMany(p => p.AspNetUserTokens)
                    .HasForeignKey(d => d.UserId);
            });

            modelBuilder.Entity<Clean>(entity =>
            {
                entity.Property(e => e.DateEntered).HasColumnType("datetime");

                entity.Property(e => e.DateUpdated).HasColumnType("datetime");

                entity.Property(e => e.Description).HasMaxLength(512);

                entity.Property(e => e.Name).HasMaxLength(50);
            });

            modelBuilder.Entity<Country>(entity =>
            {
                entity.Property(e => e.DateEntered).HasColumnType("datetime");

                entity.Property(e => e.DateUpdated).HasColumnType("datetime");

                entity.Property(e => e.Description).HasMaxLength(512);

                entity.Property(e => e.Name).HasMaxLength(50);

                entity.Property(e => e.AppleName).HasMaxLength(50);

                entity.Property(e => e.GoogleName).HasMaxLength(50);
            });

            modelBuilder.Entity<PoopLocation>(entity =>
            {
                entity.HasIndex(e => e.AspNetUsersId);

                entity.HasIndex(e => e.PostalCode);

                entity.HasIndex(e => e.ProvinceId);

                entity.Property(e => e.Address1).HasMaxLength(100);

                entity.Property(e => e.Address2).HasMaxLength(100);

                entity.Property(e => e.City).HasMaxLength(100);

                entity.Property(e => e.DateEntered).HasColumnType("datetime");

                entity.Property(e => e.DateUpdated).HasColumnType("datetime");

                entity.Property(e => e.PostalCode).HasMaxLength(50);

                entity.HasOne(d => d.AspNetUsers)
                    .WithMany(p => p.PoopLocation)
                    .HasForeignKey(d => d.AspNetUsersId)
                    .HasConstraintName("FK_PoopLocation_AspNetUsersId");

                entity.HasOne(d => d.Clean)
                    .WithMany(p => p.PoopLocation)
                    .HasForeignKey(d => d.CleanId)
                    .HasConstraintName("FK_PoopLocation_CleanId");

                entity.HasOne(d => d.Province)
                    .WithMany(p => p.PoopLocation)
                    .HasForeignKey(d => d.ProvinceId)
                    .HasConstraintName("FK_PoopLocation_ProvinceId");
            });

            modelBuilder.Entity<Province>(entity =>
            {
                entity.HasIndex(e => e.CountryId);

                entity.Property(e => e.Abbreviation).HasMaxLength(5);

                entity.Property(e => e.AppleName).HasMaxLength(50);

                entity.Property(e => e.DateEntered).HasColumnType("datetime");

                entity.Property(e => e.DateUpdated).HasColumnType("datetime");

                entity.Property(e => e.Description).HasMaxLength(512);

                entity.Property(e => e.GoogleName).HasMaxLength(10);

                entity.Property(e => e.Name).HasMaxLength(50);

                entity.HasOne(d => d.Country)
                    .WithMany(p => p.Province)
                    .HasForeignKey(d => d.CountryId)
                    .HasConstraintName("FK_Province_Country");
            });
        }
    }
}
4

3 回答 3

12

问题可能是因为您的类AspNetRoleClaims未正确继承自IdentityRoleClaim. TRoleClaim从泛型类到表,它有自己的配置AspNetRoleClaims

builder.Entity<TRoleClaim>(b =>
{
    b.HasKey(rc => rc.Id);
    b.ToTable("AspNetRoleClaims");
});

因此,如果您没有向构造函数显示正确的类型,它将使用自己的实现,IdentityRoleClaim该实现与您的AspNetRoleClaims类不同。在这种情况下,您试图创建具有不同类的同一个表。

要解决此问题,请尝试使用构造函数提供它所需的所有泛型类型:

public partial class PoopTheWorldContext : IdentityDbContext<ApplicationUser, 
    ApplicationRole, Guid, AspNetUserClaims, AspNetUserRoles, AspNetUserLogins, 
    AspNetRoleClaims, AspNetUserTokens>
{
    //your code here
}

您必须执行与您所做的相同的继承,并ApplicationUser在所有其他类ApplicationRole中使用Guidkey。

public class AspNetUserTokens : IdentityUserToken<Guid>{ /*your code here*/ }
public class AspNetRoleClaims : IdentityRoleClaim<Guid>{ /*your code here*/ }
public class AspNetUserLogins : IdentityUserLogin<Guid>{ /*your code here*/ }
public class AspNetUserRoles : IdentityUserRole<Guid>{ /*your code here*/ }
public class AspNetUserClaims : IdentityUserClaim<Guid>{ /*your code here*/ }

最后,您不需要创建所有这些 DbSet,除非您希望给它们另一个名称,因为它们已经在基类中声明。例如,AspNetRoleClaims被声明为RoleClaims. 而且,除此之外,您应该使用DbSet<ApplicationUser> AspNetUsersandDbSet<ApplicationRole> AspNetRoles而不是DbSet<AspNetRoles> AspNetRolesandDbSet<AspNetUsers> AspNetUsers因为这些是您传递给基类的类。如果您不这样做,您将收到您试图避免的相同错误。

如果要查看 DbSet 声明和表配置:

身份数据库上下文

身份用户上下文

于 2017-10-17T02:20:26.007 回答
1

解决删除public virtual DbSet上下文文件的所有 AspNetUsers 标识:

...

 public partial class ...MyContext : IdentityDbContext


public MyContext (DbContextOptions<MyContext > options)
        : base(options)
    {
    }

    //public virtual DbSet<AspNetRoleClaims> AspNetRoleClaims { get; set; }
    //public virtual DbSet<AspNetRoles> AspNetRoles { get; set; }
    //public virtual DbSet<AspNetUserClaims> AspNetUserClaims { get; set; }
    //public virtual DbSet<AspNetUserRoles> AspNetUserRoles { get; set; }
于 2020-04-15T11:30:13.323 回答
0

这是因为该表的模板已经存在。尝试这样做。它对我有用。

公共 DbSet<IdentityRoleClaim< 字符串 >>

上面的代码解决了这个问题,但要记住一件重要的事情:如果类继承了 IdentityDbContext,则不需要包含 DbSet,因为实体框架设计将理解必须创建表。

内部类 AppDbContext : IdentityDbContext

于 2021-12-08T02:29:23.623 回答