0

我对在几个对象之间正确设置实体框架有疑问。这三个对象/表是:Company、Orders、Channels Company 与 Orders 是一对多 Company 与 Channels 是一对多 Channels 与 Orders 是一对多

当我按如下方式设置它们时,我得到“可能导致循环或多个级联路径”错误。

public class Order
{
    /// <summary>
    /// System Generator OrderNumber
    /// </summary>
    [Key]
    public int ID { get; set; }

    /// <summary>
    /// Company associated to this order
    /// </summary>
    [ForeignKey("MerchantId")]
    public virtual Company { get; set; }
    public int CompanyId { get; set; }
    /// <summary>
    /// ID of the channel that provided this information
    /// </summary>
    [ForeignKey("SourceChannelId")]
    public virtual Channel { get; set; }
    public int ChannelId { get; set; }
 }
 public class Company
 {
     public List<Order> Orders{get;set;}
     public List<Channel> Channels{get;set;}
 }
 public class Channel
 {
     public List<Order> Orders{get;set;}
 }

我知道我可以通过转到渠道然后转到公司来消除订单中与公司的链接,但是在某些情况下订单可能没有渠道。但是从来没有一个订单没有公司的情况。还有第三个对象与订单有一对多关系,但我可以弄清楚如果我让前两个正常工作:)

我更喜欢使用 dataannotations 方法,但流利的也很好。

4

1 回答 1

0

这不仅仅是实体框架的问题,而是 SQL 的问题。即使在那里你也不能做同样的事情。

默认情况下,Entity Framework 设置为在删除父级时创建级联删除。

现在想象一下这种情况:

  • 您有实体 A
  • 你有实体 B,它对实体 A 有 FK
  • 你有实体 C,它对实体 A 有 FK,对实体 B 有 FK

您触发实体 A 的删除,现在实体 C 有两个删除路径:

  • C通过FK删除到A
  • C 通过 FK 删除到 B 再通过 FK 删除到 A

这是 SQL 无法处理的,因为它不知道哪个路径具有优先级,这称为多级联删除路径。

只有一种方法可以解决这个 AFAIK,它需要流畅的 API。您需要将实体 C 的 FK 之一设置为 Cascade Delete = false。

可以在实体框架中全局关闭级联删除,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

    base.OnModelCreating(modelBuilder);
}

编辑:

这将删除从 A 到 C 的删除路径,但将保留 ABC 路径。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>()
                .HasMany(x => x.Orders)
                .WithRequired(x => x.Company)
                .WillCascadeOnDelete(false);

}
于 2013-09-20T22:21:12.097 回答