[英]Entity Framework: How do I delete table rows that reference each other?
How do I delete the order without getting this exception?如何在不出现此异常的情况下删除订单?
UserLicenses
references SerialOnOrderDetails
and vice-versa: UserLicenses
引用SerialOnOrderDetails
,反之亦然:
The DELETE statement conflicted with the REFERENCE constraint "FK_SerialsOnOrderDetail_UserLicenses".
DELETE 语句与 REFERENCE 约束“FK_SerialsOnOrderDetail_UserLicenses”冲突。 The conflict occurred in database "sales", table "dbo.SerialsOnOrderDetail", column 'UserLicenseId'.
冲突发生在数据库“sales”、表“dbo.SerialsOnOrderDetail”、列“UserLicenseId”中。
Delete confirmed controller action code:删除确认的 controller 动作码:
[Authorize(Roles = "admin")]
[HttpPost, ActionName("Delete")]
public async Task<ActionResult> DeleteConfirmed(int id)
{
Order order = GetOrderById(id);
if (order.UserLicenses.Count > 0)
{
context.UserLicenses.RemoveRange(order.UserLicenses);
}
if (order.SerialsOnOrderDetails.Count > 0)
{
context.SerialsOnOrderDetails.RemoveRange(order.SerialsOnOrderDetails);
}
context.Orders.Remove(order);
context.SaveChanges(); // Exception here !!!
}
Additional classes:附加类:
public partial class UserLicense
{
public string Id { get; set; }
public int OrderId { get; set; }
public string ProductId { get; set; }
public int CustomerId { get; set; }
public string AssignedUserId { get; set; }
public bool IsActive { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
public virtual Customer Customer { get; set; }
public virtual Order Order { get; set; }
public virtual Product Product { get; set; }
public virtual ICollection<SerialsOnOrderDetail> SerialsOnOrderDetails { get; set; }
}
public partial class SerialsOnOrderDetail
{
public int orderID { get; set; }
public string serial { get; set; }
public string productID { get; set; }
public string UserLicenseId { get; set; }
public int customerID { get; set; }
public virtual Product Product { get; set; }
public virtual Serial Serial1 { get; set; }
public virtual Order Order { get; set; }
public virtual UserLicense UserLicense { get; set; }
public virtual Customer Customer { get; set; }
}
public partial class Order
{
public Order()
{
this.OrderDetails = new HashSet<OrderDetail>();
this.SerialsOnOrderDetails = new HashSet<SerialsOnOrderDetail>();
this.UserLicenses = new HashSet<UserLicense>();
}
public int orderID { get; set; }
public int customerID { get; set; }
public string promoCodeID { get; set; }
public System.DateTime date { get; set; }
public Nullable<int> resellerID { get; set; }
public string invoiceID { get; set; }
public string poNumber { get; set; }
public Nullable<System.DateTime> paymentDate { get; set; }
public Nullable<bool> validated { get; set; }
public string resellerOrderID { get; set; }
public Nullable<int> parentOrderID { get; set; }
public int months { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
public virtual PromoCode PromoCode { get; set; }
public virtual Reseller Reseller { get; set; }
public virtual ICollection<SerialsOnOrderDetail> SerialsOnOrderDetails { get; set; }
public virtual Order ParentOrder { get; set; }
public virtual ICollection<UserLicense> UserLicenses { get; set; }
}
Did you verify if UserLicenses and SerialsOnOrderDetails collections are properly loaded and not empty?您是否验证了 UserLicenses 和 SerialsOnOrderDetails collections 是否正确加载且不为空? Are you sure removerange is the proper way to do it?
您确定 removerange 是正确的方法吗? I suggest you to read a few tutorials about EF if you are not used to it.
如果你不习惯,我建议你阅读一些关于 EF 的教程。
Maybe you'll have to update GetOrderById with.Include("....") directives to load these collections, or load the related items manually.也许您必须使用.Include("....") 指令更新 GetOrderById 以加载这些 collections,或手动加载相关项目。
That constraint message you quote is from the underlying SQL Server.您引用的约束消息来自底层 SQL 服务器。 It's not an EF error as such, it's passed through.
这不是一个EF错误,它已经通过了。
When I get this sort of problem in TSQL the solution is generally to delete both of the mutually referencing rows in a single transaction.当我在 TSQL 中遇到此类问题时,解决方案通常是在单个事务中删除两个相互引用的行。
While I'm not terribly familiar with EF, a quick search turn up this example of putting multiple operations into a single transactional context instead of the default behaviour of a single transaction per operation.虽然我对 EF 不是很熟悉,但通过快速搜索可以找到将多个操作放入单个事务上下文的示例,而不是每个操作单个事务的默认行为。
{
context.Database.Log = Console.WriteLine;
using (DbContextTransaction transaction = context.Database.BeginTransaction())
{
try
{
Author author1 = new Author() { Name = "Mark" };
Author author2 = new Author() { Name = "John" };
context.Authors.Add(author1);
context.SaveChanges();
context.Authors.Add(author2);
context.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
}
}
I notice another respondent describes other things that could be wrong.我注意到另一位受访者描述了其他可能是错误的事情。 It is entirely possible that we are both right and there are multiple issues to resolve.
完全有可能我们都是对的,并且有多个问题需要解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.