EF Core中的0-1自我引用关系

时间:2019-02-14 20:34:25

标签: c# entity-framework entity-framework-core

想法:我有一个Key实体,可以延迟将其替换(旋转)为其他Key。我当时想将其实现为:

ConsumerFactory

因此,当我要替换它时,我将创建另一个密钥,然后相互引用新的和旧的密钥。而且,如果其中任何一个被删除,另一个也将被删除。

这就是我通过Fluent映射实现的方式:

class Key {
    string Id;
    string ReplacesId;
    Key Replaces;
    string ReplacedById;
    Key ReplacedBy;
    DateTime Expires;
    // ...
}

替换逻辑:

modelBuilder.Entity<Key>().HasOne(x => x.ReplacedBy)
            .WithOne(x => x.Replaces)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.Cascade);

但是似乎oldKey.ReplacedBy = newKey; oldKey.ReplacedById = newKey.Id; newKey.Replaces = oldKey; newKey.ReplacesId = oldKey.Id; _dbContext.Keys.Update(newKey); _dbContext.Keys.Update(oldKey); await _dbContext.SaveChangesAsync(); ReplacedById或它们之一像常规字段而不是FK一样被使用,因为当我尝试删除其中一个时,它们不会级联。

我可以做这个工作吗,还是只介绍ReplacesId表?

1 个答案:

答案 0 :(得分:2)

  

但是似乎ReplacedById ReplacesId或其中之一的用法与常规字段ant而不是FK相同,因为当我尝试删除其中之一时,它们不会级联。

这是因为您的Fluent API配置不正确。实际上应该如下:

modelBuilder.Entity<Key>().HasOne(k => k.Replaces)
                          .WithOne()
                          .HasForeignKey<Key>(k => k.ReplacesId)
                          .IsRequired(false);

modelBuilder.Entity<Key>().HasOne(k => k.ReplacedBy)
                          .WithOne()
                          .HasForeignKey<Key>(k => k.ReplacedById)
                          .IsRequired(false);

现在一切都会生成并按预期工作!

注意:它将生成onDelete: ReferentialAction.Restrict,因为您不能在它们之间级联,因为它将导致多个级联路径。