EF Core-如何允许对具有两个其他复杂对象列表的复杂对象进行级联删除?

时间:2018-11-07 11:12:50

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

我正在努力使其正常工作

我希望有一个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:“经销商”不能用作实体类型“汽车”的属性,因为它已配置为导航。”

尝试#2 同时:

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

它正常工作,但显示警告

  

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

Data in db

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

  

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'被多次指定。'

#尝试#3.1

因此,将Guid DealerID重命名为例如Guid DealerID123

大喊

  

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

任何人都知道如何使它工作吗?

1 个答案:

答案 0 :(得分:0)

由于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中,我做了如下操作:

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