【问题标题】:How to allow cascade delete for complex object that has two lists of other complex objects?如何允许级联删除具有两个其他复杂对象列表的复杂对象?
【发布时间】:2019-09-09 12:40:38
【问题描述】:

我正在努力让它发挥作用。

我想要一个 Dealer,他有两个相同类型的 Items 列表相关,但我也希望能够级联删除它们。

public class Dealer
{
    [Key]
    public Guid Id { get; set; }

    public string Name { get; set; }

    public List<Car> OldCars { get; set; } = new List<Car>();

    public List<Car> NewCars { get; set; } = new List<Car>();
}

public class Car
{
    [Key]
    public Guid Id { get; set; }

    public string Model { get; set; }

    public Dealer Dealer { get; set; }
}

我一直在尝试的:

尝试 #1

modelBuilder.Entity<Car>()
.HasOne(s => s.Dealer)
.WithMany(s => s.OldCars)
.HasForeignKey(x => x.Dealer)
.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Car>()
.HasOne(s => s.Dealer)
.WithMany(s => s.NewCars)
.HasForeignKey(x => x.Dealer)
.OnDelete(DeleteBehavior.Cascade);

System.InvalidOperationException: ''Dealer' 不能用作实体类型'Car' 的属性,因为它被配置为导航。'

尝试 #2 同时:

modelBuilder.Entity<Car>()
.HasOne(s => s.Dealer)
.WithMany(s => s.NewCars)
.HasPrincipalKey(x => x.Id) <--- Principal!
.OnDelete(DeleteBehavior.Cascade);     

它工作正常,但显示警告

警告:Microsoft.EntityFrameworkCore.Model[10605] 在没有配置外键属性的情况下,“Car”和“Dealer”之间存在多种关系,导致 EF 在“Car”上创建影子属性,其名称取决于发现顺序。

不幸的是,在尝试执行删除(级联)时会引发异常:

SqlException:DELETE 语句与 REFERENCE 约束“FK_Cars_Dealers_DealerId1”冲突。冲突发生在数据库“testDB”、表“dbo.Cars”、列“DealerId1”中。 声明已终止。

尝试 #3

当我将经销商 ID 添加到汽车时

public class Car
{
    [Key]
    public Guid Id { get; set; }

    public string Model { get; set; }

    public Dealer Dealer { get; set; }

    public Guid DealerID { get; set; }
}

它大喊大叫

System.Data.SqlClient.SqlException: '无法在此上下文中创建、删除、启用或禁用多个名为 'FK_Cars_Dealers_DealerId' 的约束、列、索引或触发器。不允许重复名称。 每个表中的列名必须是唯一的。表 'Cars' 中的列名 'DealerId' 被指定了多次。'

#Attempt #3.1

所以,在将 Guid DealerID 重命名为 Guid DealerID123 之后

它大叫

SqlException:INSERT 语句与 FOREIGN KEY 约束“FK_Cars_Dealers_DealerID123”冲突。冲突发生在数据库“testDB”、表“dbo.Dealers”、“Id”列中。 声明已终止。

有人知道如何让它工作吗?

【问题讨论】:

  • 您需要覆盖该行为并使用流利的 api 添加外键,例如 '.HasOn() 和 .WithMany()'。
  • 查看这里如何实现多重关系stackoverflow.com/questions/47728331/…
  • 这样的设计引入了不允许级联删除的多级联路径问题。您最好通过提供单个集合(关系)Cars 并将IsOld 或类似属性添加到Car 模型来避免它。拥有所有汽车后,您始终可以使用简单的 LINQ 模拟您当前的收藏。
  • DealerCar是什么关系?在Dealer的基础上,会有很多Cars。一个Car 是否只属于一个Dealer,或者一个Car 可能与Dealers 不同,甚至是一个DealerOldCarNewCar。您需要重新检查您的业务。或者,您可以尝试定义数据库最火,然后尝试生成模型代码。
  • 我也对这个问题感兴趣,你找到答案了吗?

标签: c# sql-server asp.net-core entity-framework-core


【解决方案1】:

感谢 Ivan Stoev 的推荐,我设法解决了如下问题:

public class Dealer
{
   [Key]
   public Guid Id { get; set; }
   public string Name { get; set; }
   [NotMapped]
   public List<Car> OldCars { get; set; } => NewCars.Where(c => c.IsOld == true);
   public List<Car> NewCars { get; set; } = new List<Car>();
}

public class Car
{
   [Key]
   public Guid Id { get; set; }
   public string Model { get; set; }
   public Dealer Dealer { get; set; }
   public bool IsOld { get; set; }
}

在 EF6 模型构建器中,我执行以下操作:

modelBuilder.Entity<Dealer>()
.HasMany(d => d.NewCars)
.WithRequired()
.WillCascadeOnDelete(true);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多