【问题标题】:EF Core circular reference on ASP.NET Core user classASP.NET Core 用户类上的 EF Core 循环引用
【发布时间】:2017-08-01 08:25:34
【问题描述】:

我正在寻找关于 EF Core 和 ASP.NET Core 的一些建议。简而言之,我正在寻找解决循环引用的最佳方法。

基本前提是这样的:我有一个 User 对象,其中包含一个 ICollection Character 对象,每个 Character 对象都包含一个关联的用户。

public class ApplicationUser : IdentityUser
{       
    public ICollection<Character> Characters { get; set; }
}
public class Character
{
    public Guid Id { get; set; }

    [Required]
    public ApplicationUser User { get; set; }

    // other properties
}

这似乎不会导致应用程序本身出现任何问题,因为 EF 处理循环引用时不会出现问题。 问题是在数据库级别我在这两个表(AspNetUser 和 Characters)上有两个外键有效地指向彼此,这意味着我将无法从数据库中删除任一实体的实例,因为它会违反相应的外键键约束。

我对 ASP.NET Core 有点陌生,因此可能有一些关于如何处理用户的约定或其他约定。 从应用程序的角度来看,我有一个页面,它仅显示字符列表以及相关用户的用户名。我目前认为最好从 Character 类中删除 User 属性并将其替换为 UserId 属性(并让应用程序逻辑将正确的用户从 UserManager 中拉出),但我不确定这会得到摆脱循环外键约束。

【问题讨论】:

  • 所示模型只会生成一个 FK(Character 表中的UserId),为什么会有两个?
  • 我在这里看不到任何删除问题。

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


【解决方案1】:

您需要将父用户添加到角色(一对多关系)并使您的收藏成为虚拟:

public class ApplicationUser : IdentityUser
{       
    public virtual ICollection<Character> Characters { get; set; }
}
public class Character
{
    public Guid Id { get; set; }

    public string ParentId { get; set; }

    public string UserId { get; set; }

    [Required]
    [ForeignKey("ParentId")]
    public virtual ApplicationUser Parent { get; set; }

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

    // other properties
}

【讨论】:

  • 暗示User属性是Character对象的父用户,为什么需要第二个属性?
  • 有用户字符(读取不同的用户)还是用户有不同类型的字符(如角色)?
  • 用户有 0 个或多个字符(阅读 RPG 的字符表)并且一个角色有一个父用户。