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

问题描述 投票:4回答:1

想法:我有一个Key实体,可以被其他Key替换(轮换)延迟。我想把它实现为:

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

因此,当我想要替换它时,我会创建另一个键,然后互相引用新旧键。如果删除其中任何一个,那么另一个也会被删除。

这就是我实现的方式,使用这个Fluent映射:

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 ReplacesId或其中一个像常规字段一样使用而不是FK,因为当我尝试删除其中一个时,它们不会级联。

我可以做这个工作,还是我应该介绍Rotations/Replacements表?

c# entity-framework entity-framework-core
1个回答
2
投票

但似乎ReplacedById ReplacesId或者其中一个被用作常规字段而不是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,因为它不能在它们之间级联,因为它会导致多个级联路径。

© www.soinside.com 2019 - 2024. All rights reserved.