Entity Framework:如何删除相互引用的 table 行?
Entity Framework: How do I delete table rows that reference each other?
如何在不出现此异常的情况下删除订单?
UserLicenses
引用 SerialOnOrderDetails
反之亦然:
The DELETE statement conflicted with the REFERENCE constraint "FK_SerialsOnOrderDetail_UserLicenses". The conflict occurred in database "sales", table "dbo.SerialsOnOrderDetail", column 'UserLicenseId'.
删除已确认的控制器操作代码:
[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 !!!
}
[编辑] 添加实时数据
实时数据(Id = UserLicenseId):
额外类:
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; }
}
您是否验证过 UserLicenses 和 SerialsOnOrderDetails 集合是否正确加载且不为空?您确定 removerange 是正确的方法吗?如果你不习惯,我建议你阅读一些关于 EF 的教程。
也许您必须使用 .Include("...") 指令更新 GetOrderById 以加载这些集合,或手动加载相关项目。
您引用的约束消息来自基础 SQL 服务器。这不是 EF 错误,它已通过。
当我在 TSQL 中遇到此类问题时,解决方案通常是在单个事务中删除两个相互引用的行。
虽然我对 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();
}
}
}
我注意到另一位受访者描述了其他可能出错的地方。完全有可能我们都是对的,并且有多个问题需要解决。
如何在不出现此异常的情况下删除订单?
UserLicenses
引用 SerialOnOrderDetails
反之亦然:
The DELETE statement conflicted with the REFERENCE constraint "FK_SerialsOnOrderDetail_UserLicenses". The conflict occurred in database "sales", table "dbo.SerialsOnOrderDetail", column 'UserLicenseId'.
删除已确认的控制器操作代码:
[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 !!!
}
[编辑] 添加实时数据
实时数据(Id = UserLicenseId):
额外类:
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; }
}
您是否验证过 UserLicenses 和 SerialsOnOrderDetails 集合是否正确加载且不为空?您确定 removerange 是正确的方法吗?如果你不习惯,我建议你阅读一些关于 EF 的教程。
也许您必须使用 .Include("...") 指令更新 GetOrderById 以加载这些集合,或手动加载相关项目。
您引用的约束消息来自基础 SQL 服务器。这不是 EF 错误,它已通过。
当我在 TSQL 中遇到此类问题时,解决方案通常是在单个事务中删除两个相互引用的行。
虽然我对 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();
}
}
}
我注意到另一位受访者描述了其他可能出错的地方。完全有可能我们都是对的,并且有多个问题需要解决。