【问题标题】:How to design one to one relationship in EF Core that points only in one direction如何在 EF Core 中设计仅指向一个方向的一对一关系
【发布时间】:2020-01-31 21:27:13
【问题描述】:

我正在尝试使用 EF Core 3 设计非常简单的数据库模型,但我遇到了非常简单的关系问题。

我有类:客户、文档和地址。

public class Customer
{
    public int Id { get; set; }

    public Address Address { get; set; }
}

public class Document
{
    public int Id { get; set; }

    public Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }

    public string Street { get; set; }

    public string City { get; set; }
}

所以我想在不同的实体中使用通用地址。

我正在尝试通过以下方式对其进行建模:

public void Configure(EntityTypeBuilder<Customer> builder)
{
    builder.HasKey(f => f.Id);
    builder.HasOne(f => f.Address).WitMany().IsRequired().OnDelete(DeleteBehavior.Cascade);
}

public void Configure(EntityTypeBuilder<Document> builder)
{
    builder.HasKey(f => f.Id);
    builder.HasOne(f => f.Address).WitMany().IsRequired().OnDelete(DeleteBehavior.Cascade);
}

public void Configure(EntityTypeBuilder<Address> builder)
{
    builder.HasKey(f => f.Id);
    builder.Property(f => f.Street);
    builder.Property(f => f.City);
}

但问题是,当我的文档附有地址并尝试删除该文档时,该地址不会被删除。由于某种原因,地址是文档的主体。

如何建模这种关系?我不能在 Address 实体中拥有导航属性,因为 Address 可以在多个不同的实体中用作地址的通用表示。

【问题讨论】:

  • 从实体中删除 DeleteBehavior.Cascade。这不适用于共享实体。您需要的是onDelete: ReferentialAction.SetNull 并将对文档的所有引用设置为空,然后再删除它。
  • 但是能解决我删除Document后不删除Address的问题吗?当我调用 dbContext.Remove(document) 时,我希望它自动删除附加到它的 document.Address 实体。
  • 您无法删除它,因为 Address 已附加到 Customer。在这种情况下不要使用级联删除。步骤 1. 将 Address 的每个引用设置为 null。步骤 2. 删除Address。第三步:删除Document
  • 这在关系数据库中是不可能的,因此在 EF(无论是否为核心)中是不可能的。 Address 可以配置为与单个主体实体的一对一的依赖方。但是你想在多个实体中使用它,所以 PK 不能用作 FK。唯一的方法是创建 2 个(或 N 个)互斥 FK。
  • 另一种选择是将Address 设为owned type,但这会显着改变数据库模型。

标签: c# .net entity-framework-core ef-core-3.0


【解决方案1】:

感谢 Ivan 指出这是不可能的。我会按照 Gerd 的建议使用自有类型。

【讨论】:

    猜你喜欢
    • 2013-12-28
    • 2021-07-21
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2018-12-03
    • 2019-07-25
    • 2021-06-25
    • 1970-01-01
    相关资源
    最近更新 更多