【问题标题】:Entity Framework Many to Many Cascade Delete Issue实体框架多对多级联删除问题
【发布时间】:2012-08-02 14:29:10
【问题描述】:

在处理代码优先 EF 项目时遇到一个奇怪的问题。

我有以下实体:

public class Booking
{
    public Guid BookingId { get; set; }
    public virtual List<AccountingDocumentItem> AccountingDocumentItems { get; set; }
}

public class AccountingDocumentItem
{
    public Guid AccountingDocumentItemId { get; set; }

    public virtual List<Employee> Employees { get; set; }
    public virtual List<Booking> Bookings { get; set; }
}

public class Employee
{
    public Guid EmployeeId { get; set; }
    public string Name { get; set; }

    public virtual List<AccountingDocumentItem> AccountingDocumentItems { get; set; }
}

如您所见,AccountingDocumentItem 与 Bookings 和 Employees 之间存在多对多关系。在配置我的 AccountingDocumentItem 时,我使用以下内容:

    public AccountingDocumentItemConfiguration()
    {
        HasMany(x => x.Employees);
        HasMany(x => x.Bookings);
    }

奇怪的是,这对员工来说非常有效。我创建了一个 AccountingDocumentItemEmployees 表。但对于预订,我收到以下错误:

“在表 'AccountingDocumentItemBookings' 上引入 FOREIGN KEY 约束 'FK_dbo.AccountingDocumentItemBookings_dbo.Bookings_Booking_BookingId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。”

现在我尝试按照下面的代码行来做这件事:

 HasMany(x => x.Bookings).WithMany(b => b.AccountingDocumentItems)...

但是我只能选择使用上面的行做一个 Map,没有做一个 WillCascadeOnDelete(false) 的选项。

谁能指出我做错了什么,因为与我处理员工的方式相比,我看不出有任何区别。

编辑:

我原来的帖子缩写了实体,这可能是问题出现的地方。这是完整的实体:

public class AccountingDocument
{
    public Guid AccountingDocumentId { get; set; }
    public Guid SiteId { get; set; }
    public virtual Site Site { get; set; }
    public Guid? ClientId { get; set; }
    public virtual Client Client { get; set; }
    public Guid? SupplierId { get; set; }
    public virtual Supplier Supplier { get; set; }
    public string DocumentNumber { get; set; }
    public string Reference { get; set; }
    public string Description { get; set; }
    public string Notes { get; set; }
    public Guid LinkedAccountingDocumentId { get; set; }
    public virtual AccountingDocument LinkedAccountingDocument { get; set; }
    public byte AccountingDocumentTypeId { get; set; }
    public DateTime CreationDate { get; set; }
    public DateTime DocumentDate { get; set; }
    public decimal Total { get; set; }
    public Guid UserId { get; set; }
    public virtual User User { get; set; }
    public string Room { get; set; }
    public virtual List<AccountingDocumentItem> AccountingDocumentItems { get; set; }
}

public class AccountingDocumentItem
{
    public Guid AccountingDocumentItemId { get; set; }

    public Guid AccountingDocumentId { get; set; }
    public virtual AccountingDocument AccountingDocument { get; set; }

    public string Description { get; set; }

    public Guid TaxId { get; set; }
    public virtual Tax Tax { get; set; }

    public decimal Quantity { get; set; }
    public string Unit { get; set; }

    public decimal Cost { get; set; }
    public decimal SellInclusive { get; set; }
    public decimal SellExclusive { get; set; }
    public decimal DiscountPercentage { get; set; }
    public decimal TotalInclusive { get; set; }
    public decimal TotalExclusive { get; set; }
    public decimal CommissionInclusive { get; set; }
    public decimal CommissionExclusive { get; set; }
    public int LoyaltyPoints { get; set; }
    public bool IsSeries { get; set; }

    public byte ItemType { get; set; }

    public Guid? ServiceId { get; set; }
    public virtual Service Service { get; set; }
    public Guid? ProductId { get; set; }
    public virtual Product Product { get; set; }
    public Guid? VoucherId { get; set; }
    public virtual Voucher Voucher { get; set; }

    public int SortOrder { get; set; }

    public Guid? SourceId { get; set; }
    public virtual Source Source { get; set; }

    public Guid? CostCentreId { get; set; }
    public virtual CostCentre CostCentre { get; set; }

    public Guid? ClientId { get; set; }
    public virtual Client Client { get; set; }

    public Guid PackageGroupId { get; set; }
    public Guid PackageServiceId { get; set; }

    public virtual List<Employee> Employees { get; set; }
    public virtual List<Booking> Bookings { get; set; }
    public virtual List<MedicalDiagnosis> MedicalDiagnoses { get; set; }
}

public class Booking
{
    public Guid BookingId { get; set; }

    public Guid SiteId { get; set; }
    public Site Site { get; set; }

    public Guid? ClientId { get; set; }
    public Client Client { get; set; }

    public Guid BookingStateId { get; set; }
    public BookingState BookingState { get; set; }

    public virtual List<AccountingDocumentItem> AccountingDocumentItems { get; set; }
}

还有我的配置:

public class AccountingDocumentConfiguration : EntityTypeConfiguration<AccountingDocument>
{
    public AccountingDocumentConfiguration()
    {
        Property(x => x.Reference).HasMaxLength(200);
        HasRequired(x => x.Site);
        Property(x => x.DocumentNumber).IsRequired().HasMaxLength(100);
        Property(x => x.Reference).HasMaxLength(200);
        Property(x => x.Description).HasMaxLength(500);
        Property(x => x.Notes).HasMaxLength(500);
        HasOptional(x => x.LinkedAccountingDocument);
        Property(x => x.AccountingDocumentTypeId).IsRequired();
        Property(x => x.CreationDate).IsRequired();
        Property(x => x.DocumentDate).IsRequired();
        Property(x => x.Total).IsRequired();
        Property(x => x.Room).HasMaxLength(50);
    }
}

public class AccountingDocumentItemConfiguration : EntityTypeConfiguration<AccountingDocumentItem>
{
    public AccountingDocumentItemConfiguration()
    {
        Property(x => x.Description).IsRequired().HasMaxLength(200);
        HasMany(x => x.Employees);
        HasMany(x => x.Bookings);
        HasMany(x => x.MedicalDiagnoses);
        Property(x => x.Unit).HasMaxLength(50);
    }
}

【问题讨论】:

  • 我完全按照上面的方式复制了你的代码,它对我有用,你是缩写吗?如果是这样,您可以发布模型的其余部分吗?
  • 嗨,马克,是的,我确实缩写了实体,我已经用完整的实体进行了编辑。

标签: entity-framework-4 ef-code-first many-to-many code-first


【解决方案1】:

即使上面添加的文本对我有用,一旦我注释掉上面未完全定义的添加的导航属性。 FK 错误意味着如果您碰巧删除,可能会出现竞争条件(请参阅article),但这里有什么我不知道。您需要对数据库进行级联删除吗?如果没有,您可以将其关闭 - 我意识到这是一个非常广泛的小问题。

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();  

如果这不是一个选项 - 这是您没有包含的其他内容。您有 Bookings 表的映射吗?看起来 Bookings 有一个必需的站点 - 删除一个站点是否可能会触发一系列其他内容的删除?看起来站点可以执行类似此站点 -> 帐户文档 -> 会计文档项目.. 站点 -> 可能预订?

这是另一个可能相关的SO question

【讨论】:

    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2014-12-20
    相关资源
    最近更新 更多