【问题标题】:EF Core relationship throwing error when creating the database创建数据库时 EF Core 关系抛出错误
【发布时间】:2019-08-22 02:46:56
【问题描述】:

我有一个Address 类,我在Customer 类和Order 类中使用它:

public class Address
{
    public Customer Customer { get; set }
    ...
}

public class Customer
{
    ...
    public List<Address> Addresses { get; set;}
}

public class Order
{
    ...
    public Customer Curstomer { get; set; }
    public Address BillingAddress { get; set;}
    public Address ShippingAddress { get; set;}
}

我成功创建了迁移,但是当我尝试 update-database 时,我收到以下错误:

引入 FOREIGN KEY 约束 表“订单”上的“FK_Order_Address_ShippingAddressId”可能会导致循环 或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建 约束或索引。查看以前的错误。

建立这种关系的正确方法是什么?这种建模是否正确?因为Address 是与Customer 相关的属性对我来说似乎很奇怪,但我也在Order 上使用它,但是在OrderAddresses 表中复制地址似乎也是错误的。

【问题讨论】:

    标签: entity-framework-core ef-core-2.0


    【解决方案1】:

    要解决此问题,请将迁移中外键的onDeleteReferentialAction 更改为Cascade 以外的其他值。 Restrict 可能是一个不错的选择。它看起来像这样:

    constraints: table =>
                {
                    table.PrimaryKey("PK_Order", x => x.Id);
                    table.ForeignKey(
                        name: "FK_Orders_BillingAddress_BillingAddressId",
                        column: x => x.BillingAddressId,
                        principalTable: "Addresses",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                }
    

    只需将其更改为 Restrict 或其他选项。

    为什么?

    如果您有Cascade,假设您要删除OrderBillingAddress。这将尝试将删除级联到 Order,然后将 its 删除级联到 ShippingAddress,然后尝试将 that 删除级联回订单和依此类推,因此 SQL Server 在循环级联删除时正确出错。

    另请参阅此问题:Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why?

    【讨论】:

    • 手动编辑迁移文件有效。但是,你知道我怎么能使用流畅的配置来做到这一点?要在OnModelCreatingMethod 方法中使用.OnDelete() 方法,我需要执行类似builder.Entity&lt;Order&gt;().HasOne(x =&gt; x.ShippingAddress).WithOne(x =&gt; x.??????).OnDelete(xxxx) 的操作。但我没有引用 Order 类 in 到 Address 类。 Address 类引用 Customer 类。
    • 嗯,刚发现第二部分的参数不用通知了。所以这有效:modelBuilder.Entity&lt;Order&gt;().HasOne(x =&gt; x.ShippingAddress).WithMany().OnDelete(DeleteBehavior.Restrict);。谢谢
    猜你喜欢
    • 2022-01-11
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多