【问题标题】:Code first self referencing foreign key (more than one)代码优先自引用外键(多个)
【发布时间】:2016-10-16 05:09:22
【问题描述】:

我有一个以 EntityBase 作为父类的用户实体。 父类如下所示:

public class EntityBase
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid Id { get; set; }

        public bool? IsPublic { get; set; }
        public bool? IsActive { get; set; }

        public DateTime CreatedAt { get; set; }
        public DateTime? UpdatedAt { get; set; }
        public DateTime? DeletedAt { get; set; }

        public virtual User CreatedBy { get; set; }
        public Guid? CreatedById { get; set; }

        public virtual User UpdatedBy  { get; set; }
        public Guid? UpdatedById { get; set; }

        public virtual User DeletedBy { get; set; }
        public Guid? DeletedById { get; set; }
    }

用户类:

public class User : EntityBase
{
    public string Username { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public string Token { get; set; }
    public DateTime LastLogin { get; set; }
    public DateTime LastAction { get; set; }
    public bool IsLocked { get; set; }
    public bool IsAdmin { get; set; }

    public virtual ICollection<Cocktail> Cocktails { get; set; }
    public virtual ICollection<Drink> DrinkVotes { get; set; }
    public virtual ICollection<Cocktail> CocktailVotes { get; set; }
}

现在我遇到了自引用的问题,因为存在循环依赖,我该如何解决这个问题?

【问题讨论】:

    标签: c# entity-framework entity code-first


    【解决方案1】:

    在您的上下文中,您需要重写 OnModelCreating(DbModelBuilder),然后像这样设置关系:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                .HasOptional(f => f.CreatedBy)
                .WithMany()
                .WillCascadeOnDelete(false);
        modelBuilder.Entity<User>()
                .HasOptional(f => f.UpdatedBy)
                .WithMany()
                .WillCascadeOnDelete(false);
        modelBuilder.Entity<User>()
                .HasOptional(f => f.DeletedBy)
                .WithMany()
                .WillCascadeOnDelete(false);
    }
    

    您正在删除此处的循环引用

    1. 说明 CreatedBy、UpdatedBy 和 DeletedBy 关系是可选的
    2. 在删除时禁用级联

    【讨论】:

      【解决方案2】:

      1) 你的基础实体必须是抽象的

         public abstract class EntityBase ....
      

      2) 在子类中移动 Id,例如 UserId/CoktailId 等(可选但推荐)

      4) 使用 InverseProperty 属性来引用鸡尾酒 例如:http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx

      【讨论】:

      • 你可以把它留在基类上,你必须手动配置它。想想用例:EntityA 从 Baseclass 继承,EntityB 从 EntityA 继承?基类中的 Id 将用于 EntityA 或 EntityB。相信我还有很多其他用例会让你头疼,我对你的建议是保持简单并向下移动。
      • 第二个用例想一想如果你想建立一对一的关系你会怎么做?你的身份证必须是!!! DatabaseGeneratedOption.None !!!!所以你不得不再次使用技巧来解决问题
      • 是的,我明白了,我想我移动了外键。
      猜你喜欢
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多