【问题标题】:How to extend IdentityUser with a foreign key如何使用外键扩展 IdentityUser
【发布时间】:2021-04-29 13:52:21
【问题描述】:

我正在尝试使用外键 (BuildingID) 扩展 IdentityUser。下面是我的 ApplicationUser 类,它派生自 IdentityUser 类。添加外键的正确方法是什么?

public class ApplicationUser : IdentityUser
{
    public int BuildingID { get; set; }
}

我正在使用实体框架核心

提前致谢

【问题讨论】:

  • 通常外键用于关系数据库而不是 C# 代码。您使用的是数据库还是数据库框架?
  • 这样你只是添加了一个普通的列。您要做的就是正确添加导航属性,然后通过Fluent Api(在OnModelCreating)配置实体
  • 您使用的是 Entity Framework 还是 Entity Framework Core?
  • @atiyar 我正在使用 Entity Framework Core
  • 好的,我刚刚添加了正确的标签。

标签: c# asp.net-core entity-framework-core asp.net-core-identity


【解决方案1】:

这是一个自以为是的答案。

当使用 ASP.NET Core Identity 时,根据我的经验,最好不要使用 IdentityUser,用于身份验证等目的。但如果您的应用程序不是那么大/复杂,我认为这个用户可以与其他实体建立关系。

在您的情况下,由于 Building 和 ApplicationUser 是一对一的关系,我建议不要将外键属性放在 ApplicationUser 类中。而是将其放在 Building 类中。这样,AspNetUser 表中将不会创建新列(即,它将被单独保留),并且您将使 Building 成为依赖实体,而不是 ApplicationUser。因此,如果您使用Cascading 功能,删除Building 不会删除相关的ApplicationUser,反之亦然。

public class ApplicationUser : IdentityUser
{
    public Building Building { get; set; }
}

public class Building
{
    public int Id { get; set; }
    public string Address { get; set; }
    public int ApplicationUserId { get; set; }
    
    public ApplicationUser ApplicationUser { get; set; }    
}

配置类似于 -

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Building>().ToTable("Building");
    modelBuilder.Entity<Building>(e =>
    {
        e.HasKey(p => p.Id);
        e.Property(p => p.Id).UseIdentityColumn<int>();     
        e.Property(p => p.Address).IsRequired(false).HasColumnType<string>("nvarchar(128)");
        e.Property(p => p.ApplicationUserId).IsRequired(true);
    });
    modelBuilder.Entity<Building>()
        .HasOne(e => e.ApplicationUser)
        .WithOne(p => p.Building)
        .HasForeignKey<Building>(e => e.ApplicationUserId)
        .OnDelete(DeleteBehavior.Cascade);
}

【讨论】:

  • 当时我很困惑,出于某种奇怪的原因,我认为这是一对一的关系,但实际上是一对多的。我正在测试一种可能是解决方案的方法。感谢您的帮助!
  • 我在上面添加了我的解决方案 - 我很想听听您对此的评论,因为您比我更有经验,我想知道它是否合乎道德。
【解决方案2】:

更新:

这是一对多的方法

我将 ApplicationUser 类更改为以下内容:

public class ApplicationUser : IdentityUser
{
    public int BuildingID { get; set; }
    [ForeignKey("BuildingID")]
    public Building building { get; set; }
}

然后我通过包管理器控制台添加了迁移:

add-migration identity-user-extention

迁移完成后,我编辑了生成的代码并删除了所有创建和删除表的代码。这背后的原因是它试图重新创建我已经生成的所有表。

public partial class identity-user-extention: Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<int>(
            name: "BuildingID",
            table: "AspNetUsers",
            nullable: false,
            defaultValue: 0);

        migrationBuilder.CreateIndex(
            name: "IX_AspNetUsers_BuildingID",
            table: "AspNetUsers",
            column: "BuildingID");

        migrationBuilder.AddForeignKey(
            name: "FK_AspNetUsers_BUILDING_BuildingID",
            table: "AspNetUsers",
            column: "BuildingID",
            principalTable: "BUILDING",
            principalColumn: "BUILDING_ID",
            onDelete: ReferentialAction.Cascade);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_AspNetUsers_BUILDING_BuildingID",
            table: "AspNetUsers");

        migrationBuilder.DropIndex(
            name: "IX_AspNetUsers_BuildingID",
            table: "AspNetUsers");

        migrationBuilder.DropColumn(
            name: "BuildingID",
            table: "AspNetUsers");
    }
}

我保存了迁移,然后在包管理器控制台中运行了以下命令:

Update-Database

然后我能够成功创建一个帐户,并将 buildingID 作为外键(Buildings 表已经填充)

【讨论】:

  • 我不太确定编辑/删除迁移生成的代码。新迁移不会再次创建现有表。如果你的表格和数据没问题,那就没问题。重要的是,现在你ApplicationUser 是依赖实体,所以删除一个建筑物会删除所有相关的用户,因为EF 默认使用Cascading。我将编辑我的答案以发布新的实体配置,这样就不会发生级联。
  • 当我尝试正常运行它时,它说该表已经存在,这很奇怪(我不记得确切的问题,或者我可能解释错误,这很可能)。谢谢再次帮助!
  • @atiyar 通过删除所有相关用户,它最终非常适合我的用例!
猜你喜欢
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 2018-11-11
  • 2014-02-11
  • 2021-03-04
  • 2020-11-17
  • 1970-01-01
  • 2019-02-16
相关资源
最近更新 更多