Microsoft.AspNet.Identity.EntityFramework.IdentityUser的外键?

我在VS 2013,刚刚创建了一个MVC应用程序。

我正在创建一个对象,我打算在结果数据库中有一个AspNetUsers表的外键。 该项目确实有一个ApplicationUser(派生自IdentityUser),看起来像是与AspNetUsers表的属性列匹配。

我们如何正确地为此声明外键?

public MyObject { public string UserId { get; set; } [ForeignKey("UserId")] public ApplicationUser User { get; set;} // other properties } 

现在,我修改ApplicationUser以获得MyObjects的集合:

 public ApplicationUser : IdentityUser { public virtual ICollection MyObjects { get; set; } } 

这似乎是如何在EF Code First中进行一对多操作。 但是,当我更新数据库时,我收到的错误表明身份成员(IdentityUserLogin,IdentityUserRole等)没有定义键。 也许那些课程不打算参加EF Code First Migrations?

我可以“到后面”并通过SQL语句添加外键,但如果我想从Code First再次更新,我可能会收到错误(数据库当前不匹配旧的迁移或类似的东西)。

我们如何正确地使用外键参考这些会员表?

我还尝试使用AspNetUsers表的匹配属性创建一个AspNetUser类。 我没有在Client类上使用“public ApplicationUser”,而是声明了“public AspNetUser”。 这样做会导致迁移失败 – “未应用自动迁移,因为它会导致数据丢失”。

那么该怎么办?

ApplicationUserMyObject之间创建一对多关系很容易,并在MyObjects表中添加“UserId”外键。 我喜欢这个解决方案的是它遵循EF约定,并且模型中不需要[ForeignKey]属性:

 public class ApplicationUser : IdentityUser { public virtual ICollection 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 { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { } public DbSet MyObjects { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity() .HasRequired(c => c.ApplicationUser) .WithMany(t => t.MyObjects) .Map(m => m.MapKey("UserId")); } } 

请注意使用Fluent API在MyObjects表中创建“UserId”外键。 这个解决方案仍然可以在不添加Fluent API的情况下工作,但是按照惯例,您的外键列将在MyObjects表中命名为“ApplicationUser_Id”。

我将执行以下操作:在ApplicationUser类中,添加ForeignKey属性,

 public ApplicationUser : IdentityUser { [ForeignKey("UserID")] public virtual ICollection MyCustomUsers{ get; set; } } 

并在您的模型中,您要跟踪它所属的用户,

 public MyObject { public string UserId { get; set; } // other properties } 

您不需要将整个ApplicationUser实例存储在MyObject类中,并且将自动生成UserID 。 重要的是,类型为stringApplicationUserID也是如此!

我认为你倒退了。 也许尝试类似的东西:

 public MyCustomUser : IUser { public string Id { get; set; } public string FavoriteHairColor { get; set;} } public ApplicationUser : IdentityUser { public virtual ICollection MyCustomUsers{ get; set; } } 

我要从记忆中走出来,所以我可能会有点失望。 无论如何,重要的是让你的EF用户类inheritance自IUser。

ASP.NET Identity类不使用属性来定义关系,他们希望关系由DbContext配置。

与ASP.NET Identity, IdentityDbContext一起使用的默认DbContext包括配置。 因此,如果您使DbContext类inheritance自IdentityDbContext ,则应该全部设置。

更新

如果仍然出现错误:“未应用自动迁移,因为它会导致数据丢失。” 然后做:

 get Update-Database -Force 

如果仍然收到有关IdentityUserLogin,IdentityUserRole等的错误消息没有定义键,那么您最有可能在不调用基本方法的情况下覆盖OnModelCreating中的OnModelCreating方法。 像这样添加对基地的呼叫:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelbuilder); // your code here } 

更新结束

如果您不想从IdentityDbContextinheritance,则需要为Identity类添加一些配置。 一种方法是重写OnModelCreating 。 这是IdentityDbContext配置entity framework映射的地方。 如果将其添加到DbContext类,则应设置所需的映射。

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().HasKey(l => l.UserId); modelBuilder.Entity().HasKey(r => r.Id); modelBuilder.Entity().HasKey(r => new { r.RoleId, r.UserId }); } 
 public MyObject { .. other properties [MaxLength(128), ForeignKey("ApplicationUser")] public virtual string UserId { get; set; } public virtual ApplicationUser ApplicationUser { get; set;} }