Mic*_*uso 8 c# entity-framework poco ef-code-first ef-migrations
我在VS 2013,刚刚创建了一个MVC应用程序.
我正在创建一个对象,我打算在结果数据库中有一个AspNetUsers表的外键.该项目确实有一个ApplicationUser(派生自IdentityUser),看起来像是与AspNetUsers表的属性列匹配.
我们如何正确地为此声明外键?
public MyObject
{
public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser User { get; set;}
// other properties
}
Run Code Online (Sandbox Code Playgroud)
现在,我修改ApplicationUser以获得MyObjects的集合:
public ApplicationUser : IdentityUser
{
public virtual ICollection<MyObject> MyObjects { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这似乎是如何在EF Code First中进行一对多操作.但是,当我更新数据库时,我收到的错误表明身份成员(IdentityUserLogin,IdentityUserRole等)没有定义键.也许这些课程不打算参加EF Code First Migrations?
我可以"回到"并通过SQL语句添加外键,但如果我想再次从Code First更新,我可能会收到错误(数据库目前不匹配旧的迁移或类似的东西).
我们如何正确地使用外键参考这些会员表?
我还尝试使用AspNetUsers表的匹配属性创建一个AspNetUser类.我没有在Client类上使用"public ApplicationUser",而是声明了"public AspNetUser".这样做会导致迁移失败 - "未应用自动迁移,因为它会导致数据丢失".
那么该怎么办?
ApplicationUser在和 之间创建一对多关系MyObject并在表中添加“UserId”外键很容易MyObjects。[ForeignKey]我喜欢这个解决方案的地方在于它遵循 EF 约定,并且模型中不需要属性:
public class ApplicationUser : IdentityUser
{
public virtual ICollection<MyObject> MyObjects { get; set; }
}
public class MyObject
{
public int MyObjectId { get; set; }
public string MyObjectName { get; set; }
// other properties
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public DbSet<MyObject> MyObjects { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyObject>()
.HasRequired(c => c.ApplicationUser)
.WithMany(t => t.MyObjects)
.Map(m => m.MapKey("UserId"));
}
}
Run Code Online (Sandbox Code Playgroud)
请注意使用 Fluent API 在MyObjects表中创建“UserId”外键。该解决方案在不添加 Fluent API 的情况下仍然可以工作,但是按照惯例,您的外键列将在表中命名为“ApplicationUser_Id” MyObjects。
ASP.NET Identity 类不使用属性来定义关系,它们希望关系由 DbContext 配置。
与 ASP.NET Identity 一起使用的默认 DbContextIdentityDbContext<TUser>包括配置。因此,如果您让 DbContext 类继承自IdentityDbContext<ApplicationUser>您,那么您应该已准备就绪。
更新
如果仍然出现错误:“未应用自动迁移,因为这会导致数据丢失。” 然后做:
get Update-Database -Force
Run Code Online (Sandbox Code Playgroud)
如果您仍然收到有关 IdentityUserLogin、IdentityUserRole 等没有定义键的错误消息,那么您很可能在OnModelCreating不先调用基本方法的情况下覆盖 DbContext 中的方法。像这样添加对基地的调用:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelbuilder);
// your code here
}
Run Code Online (Sandbox Code Playgroud)
更新结束
如果您不想继承,IdentityDbContext则需要为 Identity 类添加一些配置。实现此目的的一种方法是重写OnModelCreating. 这是IdentityDbContext<ApplicationUser>配置实体框架映射的地方。如果将其添加到 DbContext 类中,它应该设置您需要的映射。
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 });
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10846 次 |
| 最近记录: |