实体框架多对多级联删除问题 [英] Entity Framework Many to Many Cascade Delete Issue

查看:268
本文介绍了实体框架多对多级联删除问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有以下实体:

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

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

public virtual List< Employee>员工{get;组; }
public virtual List< Booking>预订{get;组; }
}

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

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

正如你所看到的,这意味着要多对多AccountingDocumentItem与预订和员工之间的关系。配置我的AccountingDocumentItem时,我使用以下内容:

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

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



FOREIGN KEY约束简介表AccountingDocumentItemBookings上的FK_dbo.AccountingDocumentItemBookings_dbo.Bookings_Booking_BookingId可能会导致循环或多个级联路径ON删除无操作或更新无操作,或修改其他FOREIGN KEY约束。



现在我试图按照以下代码执行此操作: p>

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

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



有人可以指出我做错了什么,因为将其与我处理员工的情况进行比较我看不出任何区别。



编辑:



我的原始帖子缩写了实体,这可能是问题出现的原因。以下是完整的实体:

  public class AccountingDocument 
{
public Guid AccountingDocumentId {get;组; }
public Guid SiteId {get;组; }
public virtual Site Site {get;组; }
public Guid? ClientId {get;组; }
public virtual Client Client {get;组; }
public Guid? SupplierId {get;组;
public virtual供应商供应商{get;组; }
public string DocumentNumber {get;组; }
public string参考{get;组; }
public string描述{get;组; }
public string Notes {get;组; }
public Guid LinkedAccountingDocumentId {get;组; }
public virtual AccountingDocument LinkedAccountingDocument {get;组; }
public byte AccountingDocumentTypeId {get;组; }
public DateTime CreationDate {get;组; }
public DateTime DocumentDate {get;组; }
public decimal Total {get;组; }
public Guid UserId {get;组; }
public virtual User User {get;组; }
public string Room {get;组; }
public virtual List< AccountingDocumentItem> AccountingDocumentItems {get;组; }
}

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

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

public string描述{get;组; }

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

public decimal数量{get;组; }
public string Unit {get;组; }

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

public byte ItemType {get;组; }

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

public int SortOrder {get;组; }

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

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

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

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

public virtual List< Employee>员工{get;组; }
public virtual List< Booking>预订{get;组; }
public virtual List< MedicalDiagnosis>医疗诊断{get;组;
}

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

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

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

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

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

我的配置:

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

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


解决方案

上面添加的文本对我来说是有效的,一旦我注释了上面没有完全定义的添加的导航属性。 FK错误意味着如果碰巧删除,那么可能是一个竞争条件(请参阅文章),但是在这里我不能告诉。您需要在数据库中进行级联删除吗?如果没有,你可以把它关掉 - 我意识到这是一个很小的问题,但是在一个小问题上。

  modelBuilder.Conventions卸下摆臂< OneToManyCascadeDeleteConvention>(); 

如果这不是一个选项 - 这是你没​​有包括的其他东西。你有预订表的映射吗?看起来像预订有一个必需的网站 - 删除一个网站可能会触发一些其他的东西删除?看起来网站可以做这样的网站 - >帐户文件 - >会计文档项目..网站 - >可能预订?



这是另一个 SO问题可能是相关的。


Having a strange issue working on a code first EF project.

I have the following entities:

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; }
}

As you can see, there is meant to be many-to-many relationship between AccountingDocumentItem and both Bookings and Employees. When configuring my AccountingDocumentItem I use the following:

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

What is strange is that this works perfectly for Employees. I get a AccountingDocumentItemEmployees table created. But for Bookings I get the following error:

"Introducing FOREIGN KEY constraint 'FK_dbo.AccountingDocumentItemBookings_dbo.Bookings_Booking_BookingId' on table 'AccountingDocumentItemBookings' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints."

Now I've tried to do this along the lines of below code:

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

But I only get the option to do a Map using the above line, no option to do a WillCascadeOnDelete(false).

Can someone point out what I'm doing wrong, because comparing it to how I handle Employees I can't see any difference.

EDIT:

My original post abbreviated the entities, which is probably where the problem is arising. Here is the full entity:

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; }
}

And my configuration:

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);
    }
}

解决方案

Even with the added text above it's working for me, once I comment out the added nav properties that aren't fully defined above. The FK error means that there might be a race condition if you happen to delete (See this article), but with whats here I can't tell. Do you need to have cascading deletes on your database? If not, you could just turn it off - I realize it's a pretty broad stroke on a minor problem though.

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();  

If this is not an option - it's something else that you haven't included. Do you have mappings for the Bookings table? It looks like Bookings have a required Site - is it possible that deleting a site, could trigger a delete in a bunch of other things? It looks like Site could do something like this Site -> Account Document -> Accounting Document item.. Site -> Booking possibly?

Here's another SO question that could possibly be related.

这篇关于实体框架多对多级联删除问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆