我用EF架设了数据库,并将mydbcontext
更改为从IdentityDbContext
继承,因为我希望所有内容都在一个dbcontext
之下。
问题是,当我启动应用程序并在登录页面中写入凭据时,出现异常:
实体类型“ AspNetUserLogins”要求定义主键
我以前没听说过,因为我在打电话给base.OnModelCreating(modelBuilder);
我在做什么错了?
public partial class AdventuresContext : IdentityDbContext<ApplicationUser>
{
public AdventuresContext()
{
}
public AdventuresContext(DbContextOptions<AdventuresContext> options)
: base(options)
{
}
public virtual DbSet<Adventures> Adventures { get; set; }
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<AspNetUserTokens> AspNetUserTokens { get; set; }
public virtual DbSet<AspNetUsers> AspNetUsers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Adventures");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
modelBuilder.Entity<Adventures>(entity =>
{
entity.HasIndex(e => e.UserId);
entity.Property(e => e.CountryCodeIso03from).HasColumnName("CountryCodeISO03From");
entity.Property(e => e.CountryCodeIso03to).HasColumnName("CountryCodeISO03To");
entity.Property(e => e.Name).HasMaxLength(50);
entity.Property(e => e.ShortDescription).HasMaxLength(128);
entity.Property(e => e.Timestamp).IsRowVersion();
entity.Property(e => e.UserId).IsRequired();
entity.HasOne(d => d.User)
.WithMany(p => p.Adventures)
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Adventures_Adventures");
});
}
}
答案 0 :(得分:0)
我相信有两种方法可以解决此问题。
您可以使用getter和setter将[Key]添加到AspNetUserLogins类的公共属性上,例如:
[Key]
public int SomeFieldName {get;set;}
或者您可以使用OnModelCreating重写来调用HasNoKey(),例如:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<AspNetUserLogins>(o =>
{
o.HasNoKey();
});
}
答案 1 :(得分:0)
AspNetUsersLogins是Identity附带的标准类。它有2个主键,分别是LoginProvider和ProviderKey。我试图将它们从字符串更改为Guid,但仍然是相同的消息。我还尝试将两个属性都设置为[Key]属性,但我有一个异常:“ InvalidOperationException:实体类型'AspNetUserLogins'具有使用数据注释定义的复合主键。要设置复合主键,请使用fluent API。” 。还有其他想法吗?EF架设的AspNetUsersLogins看起来像这样:
public partial class AspNetUserLogins
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
public string ProviderDisplayName { get; set; }
public string UserId { get; set; }
public virtual AspNetUsers User { get; set; }
}
答案 2 :(得分:0)
由于您继承自IdentityDbContext
,因此无需重新创建AspNet*
DbSet,建议您删除所有内置的DbSet<AspNet*>
和modelBuilder.Entity<AspNet*>.
>
public partial class AdventuresContext : IdentityDbContext<ApplicationUser>
{
public AdventuresContext ()
{
}
public AdventuresContext (DbContextOptions<AdventuresContext> options)
: base(options)
{
}
public virtual DbSet<Adventures> Adventures { get; set; }
//remove below DbSet
//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<AspNetUserTokens> AspNetUserTokens { get; set; }
//public virtual DbSet<AspNetUsers> AspNetUsers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Adventures");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//...
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
var conn = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Adventures";
services.AddDbContext<AdventuresContext>(options =>
options.UseSqlServer(conn));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<AdventuresContext>();
}