简体   繁体   English

实体框架:如何删除相互引用的表行?

[英]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.

相关问题 当它们相互交叉引用时,如何在实体框架中加载嵌套实体? - How do I load nested entities in entity framework when they cross reference each other? 如何删除 Entity Framework Core 中的多行? - How do I delete multiple rows in Entity Framework Core? 使用实体框架,如何在两个模型上添加外键以相互引用 - Using Entity Framework, how can I add a foreign key on two models to reference each other 我应该如何禁用每个对象的实体框架表引用(外部)列表? - How should I disable Entity Framework table reference(foreign) list from each objects? 实体框架。 删除表中的所有行 - Entity Framework. Delete all rows in table 在使用带有实体框架的Table-per-Type时,如何仅获取基表行? - How do I get just the base table rows when using Table-per-Type with Entity Framework? 如何使用Entity Framework删除多行? - How can I delete multiple rows with Entity Framework? 如何在 Entity Framework Data First 中使用 FromSqlRaw 引用查找表中的字段? - How do I reference fields from a lookup table using FromSqlRaw in Entity Framework Data First? 如何在实体框架中循环创建和删除记录 - How do I create and delete records in Entity Framework in a loop 如何删除 Entity Framework.Core 中的一组记录? - How do I delete a set of records in Entity Framework .Core?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM