我这个问题已经持续了一个星期了。我已经在Web上搜索了多个源,而Stackoverflow则在Entity Framework 6(EF 6)中将Identity模型的外键引用到IdentityUser类。
我尝试过设置DbContext,Model,自定义IdentityUser类的许多不同变体。
最后,我尝试在为IdentityUserLogin,IdentityRole和IdentityUserRole实现HasKey方法时添加OnModelCreating。
以下是我目前的代码:
IdentityModel
public class ApplicationUser : IdentityUser
{
[Required]
public string Fullname { get; set; }
[Required]
public string Province { get; set; }
[Required]
public string Company { get; set; }
public virtual ICollection<Expense> Expenses { get; set; }
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;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("PacificPetEntities", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
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 });
base.OnModelCreating(modelBuilder);
}
//public DbSet<ApplicationUser> ApplicationUsers { get; set; }
}
配置
internal sealed class ExpensesConfiguration : DbMigrationsConfiguration<PacificPetExpensesDb>
{
public ExpensesConfiguration()
{
AutomaticMigrationsEnabled = true;
ContextKey = "PacificPetExpenses.Models.PacificPetExpensesDb";
}
protected override void Seed(PacificPetExpensesDb context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
internal sealed class UserConfiguration : DbMigrationsConfiguration<ApplicationDbContext>
{
public UserConfiguration()
{
AutomaticMigrationsEnabled = true;
ContextKey = "PacificPetExpenses.Models.ApplicationDbContext";
}
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
的DbContext
public class PacificPetExpensesDb : DbContext
{
public PacificPetExpensesDb()
: base("PacificPetEntities")
{
//Create database always, even If exists
Database.SetInitializer<PacificPetExpensesDb>(new CreateDatabaseIfNotExists<PacificPetExpensesDb>());
}
public DbSet<Expense> Expenses { get; set; }
}
我的模特
public class Expense : IValidatableObject
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
public string Category { get; set; }
public string Description { get; set; }
[Required]
[Display(Name = "Gross Amount")]
public double GrossAmount { get; set; }
[Required]
[Display(Name = "Tax Amount")]
public double TaxAmount { get; set; }
[Required]
[Display(Name = "Net Amount")]
public double NetAmount { get; set; }
public int Mileage { get; set; }
[Display(Name = "Mileage Rate")]
public double MileageRate { get; set; }
[Required]
[Display(Name = "Date Submitted")]
public DateTime? DateSubmitted { get; set; }
[Required]
[Display(Name = "Expense Date")]
public DateTime? ExpenseDate { get; set; }
//public string UserId { get; set; }
//[ForeignKey("UserId")]
public virtual ApplicationUser ApplicationUser { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Category == "Auto - Mileage" && Mileage == 0)
{
yield return new ValidationResult("You must enter a mileage amount if the chosen category is mileage.");
}
}
}
每次我运行我的Entity Framework代码的任何变体时,都会收到以下错误消息:
在模型生成期间检测到一个或多个验证错误:
- PacificPetExpenses.Models.IdentityUserLogin :: EntityType &#39; IdentityUserLogin&#39;没有定义键。为此定义密钥 的EntityType。
- PacificPetExpenses.Models.IdentityUserRole :: EntityType &#39; IdentityUserRole&#39;没有定义键。为此定义密钥 的EntityType。
- IdentityUserLogins:EntityType:EntitySet &#39; IdentityUserLogins&#39;基于类型&#39; IdentityUserLogin&#39;没有 键定义。
- IdentityUserRoles:EntityType:EntitySet &#39; IdentityUserRoles&#39;基于类型&#39; IdentityUserRole&#39;没有 键定义。
当我清楚的时候,在所有这些上使用HasKey方法......
请帮忙!
谢谢。
答案 0 :(得分:1)
您的代码中有2个DB上下文,因此您的程序最终得到了2个独立的数据库。您的配置适用于其他数据库。如果您想要1个数据库,只需将public DbSet<Expense> Expenses { get; set; }
移至ApplicationDbContext
。并删除PacificPetExpensesDb
课程。
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("PacificPetEntities", throwIfV1Schema: false)
{
}
public DbSet<Expense> Expenses { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
然后你不再需要OnModelCreating()
方法了。
但如果你真的需要2个单独的数据库,那么你的第二个上下文必须继承IdentityDbContext<ApplicationUser>
而不是DbContext
。