【问题标题】:How to add a foreign key reference to ASP.Net MVC 5 Identity?如何向 ASP.Net MVC 5 Identity 添加外键引用?
【发布时间】:2014-03-10 10:04:46
【问题描述】:

我有一个使用 ASP.Net 标识的新 ASP.NET MVC 5.1 项目。 它看起来可靠且有希望,但今天我花了将近 9 个小时来做​​一件简单的事情,如果使用 SQL。

我的问题是,我无法通过 CodeFirst 创建一个表,外键引用默认 AspNetUsers 表。

例如: 我创建了一个名为 - Address

的表
   public class Address
    {
        [Key]
        public string UserId { get; set; }
        public string MyAddress { get; set; }
    }

但是如何创建对 AspNetUsers 的外键引用?

我尝试将上面的属性替换为

public IdentityUser MyAddress { get; set; }
// Or
public virtual IdentityUser MyAddress { get; set; }
// Or
public virtual ApplicationUser MyAddress { get; set; }

但它们都仍然显示错误:

One or more validation errors were detected during model generation:

MiaPos.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType. 
MiaPos.Models.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType. 
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined. 
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.

我也尝试从 post 覆盖 OnModelCreating

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 });
}

但是当我运行 Add-Migration 时,它会创建 IdentityUserLogin、IdentityRole、IdentityUserRole 表并重复,只是前缀不同。 (AspNet身份)

最后我在 10 秒内通过 SQL 完成,但我只想知道为什么我不能在 CodeFirst 中完成? 以及为什么从 Microsoft 2014 新技术 做这样的事情这么难。

【问题讨论】:

标签: entity-framework


【解决方案1】:

你可以这样做。因为有时您可能需要 1-1 连接

 public class AnotherTable
    {
        [Key]
        public string UserId { get; set; }

        [ForeignKey("UserId")]
        public virtual ApplicationUser User { get; set; }
    }

【讨论】:

  • 这应该是正确的答案!如果不是 1-1 ,则创建第三个表,其中包含 AnotherTable ID 和 ApplicationUser ID
  • @MichaelMao 只是按照惯例。将您的子类外键字符串属性命名为“ApplicationUserId”,这将是约定的外键。实体名称 + ID。同样对主键有效。 'Id' 将始终是主键。
【解决方案2】:

感谢您 Gábor Plesz 的上述评论。

我找到了解决办法。

继承IdentityUser的ApplicationUser类(创建AspNetUsers表)应该创建子类(子表)的ICollection属性。

例如

public virtual ICollection<ToDo> ToDoes { get; set; }

所以 ToDo 类可以引用到 ApplicationUser

强烈推荐看看 Gábor Plesz 所说的示例。

【讨论】:

  • 非常感谢 得到解决方案
  • 请将您的答案标记为正确答案以帮助他人
  • @Cheung 如果我的实体在另一个类库项目中并且身份表在 Web 项目中,如何添加外键关系?如果您有任何想法,请告诉我?
  • 我是否需要将 IdentityUser 更改为 ApplicationUser,无论在何处使用 IdentityUser?
【解决方案3】:

如果你真的想创建一个名为 Address 的表,而不是创建一个名为 Address 的属性以作为 AspNetUsers 表中的一列生成,请执行以下操作(obs:在这种情况下,我假设一个用户可以有多个地址):

  1. 在你的地址类:

    public class Address
    {
        public string MyAddress { get; set; }
    
        // referencing the AspNetUsers table ( ApplicationUser.cs)
        public string UserId { get; set; }
        public virtual ApplicationUser User { get; set; }
    }
    
  2. 您的 ApplicationUser 类:

    public virtual ICollection<Address> Addresses { get; set; }
    
  3. 在 OnModelCreating 方法中的 DBContext 中执行以下操作(流畅的 API):

    builder.Entity<Address>()
                  .HasOne(c => c.User)
                  .WithMany(x => x.Addresses)
                  .HasForeignKey(f => f.UserId)
                  .HasConstraintName("UserId")
                  .OnDelete(DeleteBehavior.Cascade)
                  .IsRequired();
    

OBS:不要忘记在 OnModelCreating 方法上方添加这行代码:

public DbSet<Address> Addresses { get; set; }

在包管理器控制台中运行这些命令后:

Add-Migrations UserAddress

之后:

Update-Database. 

但是,如果您只想为 AspNet 用户添加一个新属性,只需在您的 ApplicationUser.cs 文件/类中创建此属性:

public class ApplicationUser : IdentityUser
    {
        public string Address { get; set; }
    }

并为您的 PMC 运行相同的命令:

Add-Migration UserAddress

之后:

Update-Database

希望这会有所帮助!

【讨论】:

  • 我是否需要将 IdentityUser 更改为 ApplicationUser,无论在何处使用 IdentityUser?
猜你喜欢
  • 2015-02-01
  • 2020-06-04
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
  • 1970-01-01
相关资源
最近更新 更多