I am a bit confused of how this cascading works. So I have these 2 entities linked together.
Sales Contract:
public class SalesContract : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Index(IsUnique = true)]
[StringLength(50)]
public string SCNo { get; set; }
[Required]
public string DeliveryAddress { get; set; }
public DateTime DeliveryDate { get; set; } = DateTime.UtcNow;
[Required]
public string Transport { get; set; }
[ForeignKey("PaymentMethod")]
public Guid PaymentMethodId { get; set; }
public virtual PaymentMethod PaymentMethod { get; set; }
public int PaymentTime { get; set; }
public string Note { get; set; }
[ForeignKey("ItemType")]
public Guid ItemTypeId { get; set; }
public ItemType ItemType { get; set; }
public Guid SalesId { get; set; }
public virtual Account Sales { get; set; }
[ForeignKey("Buyer")]
public Guid BuyerId { get; set; }
public virtual Buyer Buyer { get; set; }
[Required]
public string Status { get; set; } = "Pending"; //Pending / Approved
public Guid? ApprovedById { get; set; }
public virtual Account ApprovedBy { get; set; }
public bool? IsApproved { get; set; }
[AutoGenerated]
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
public ICollection<SalesContractItem> Items { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
this.Items.ForEach(m => { db.SalesContractItems.Remove(m); });
db.SalesContracts.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
And Sales Contract Item:
public class SalesContractItem : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[ForeignKey("Item")]
public Guid ItemId { get; set; }
public virtual Item Item { get; set; }
[ForeignKey("Color")]
public Guid ColorId { get; set; }
public virtual Color Color { get; set; }
[ForeignKey("Unit")]
public Guid UnitId { get; set; }
public virtual Unit Unit { get; set; }
[ForeignKey("ItemType")]
public Guid ItemTypeId { get; set; }
public virtual ItemType ItemType { get; set; }
public decimal Price { get; set; }
[ForeignKey("Currency")]
public Guid CurrencyId { get; set; }
public Currency Currency { get; set; }
[Required]
public decimal BaseQty { get; set; }
public decimal Remaining { get; set; }
public string Description { get; set; }
[AutoGenerated]
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
[ForeignKey("SalesContract")]
public Guid SalesContractId { get; set; }
public virtual SalesContract SalesContract { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.SalesContractItems.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
ObjectMapper class contains only functions, there is no entity property.
The full error message is this:
Introducing FOREIGN KEY constraint 'FK_dbo.SalesContractItems_dbo.SalesContracts_SalesContractId' on table 'SalesContractItems' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors.
What is wrong with these 2 entities which causes multiple cascading when delete?
NOTE
As requested these are the full entities linked to both.
public class Item : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Index(IsUnique = true)]
[StringLength(50)]
public string ItemName { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.Items.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
public class Color : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Index(IsUnique = true)]
[StringLength(50)]
public string ColorCode { get; set; }
public string ColorName { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.Colors.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
public class Unit : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Index(IsUnique = true)]
[StringLength(50)]
public string UnitName { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.Units.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
public class ItemType : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Index(IsUnique = true)]
[StringLength(50)]
public string ItemTypeName { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.ItemTypes.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
public class PaymentMethod : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
public string PaymentMethodName { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.PaymentMethods.Remove(this);
await db.SaveChangesAsync();
return true;
}
}
public class Currency : ObjectMapper
{
[Key]
[Index(IsUnique = true)]
[AutoGenerated]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Index(IsUnique = true)]
[StringLength(50)]
public string CurrencyName { get; set; }
[Required]
public string CurrencySymbol { get; set; }
public async Task<bool> Delete(MigrationDBContext db)
{
db.Currencies.Remove(this);
await db.SaveChangesAsync();
return true;
}
}