由于关联集,EF无法删除子对象 [英] EF cannot delete child object because of associationset

查看:105
本文介绍了由于关联集,EF无法删除子对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有客户和银行账户。客户可以拥有多个银行帐户,但是一个银行帐户可以有一个客户。



我正在尝试通过ID删除一个bankaccount。但是当我们删除内容时,我们实际上通过将IsActive属性设置为false来执行更新。



我的删除部分如下所示:

  var bankaccounts = from b in this.unitOfWork.BankAccounts 
其中command.Ids.Contains(b.Id)// command.ids是一个数组, id的
选择b;

this.unitOfWork.BankAccounts.DeleteObject(bankaccounts);

然后,在提交之前,我们有这个代码,将删除转换为更新,并设置IsActive属性为false

  public void Commit()
{
var addedEntities = this.GetEntitiesByState(EntityState 。添加);
foreach(添加的实体中的var entity)
{
var property = this.GetIsActiveProperty(entity);
property.SetValue(entity.Entity,true);
}

var deletedEntities = this.GetEntitiesByState(EntityState.Deleted);
foreach(deleteEntities中的var entity)
{
var property = this.GetIsActiveProperty(entity);
if(property!= null)
{
entity.State = EntityState.Modified;
property.SetValue(entity.Entity,false);
}
}

this.mapper.Commit();
}

private IEnumerable< DbEntityEntry> GetEntitiesByState(EntityState state)
{
return this.context.ChangeTracker.Entries()。其中​​(e => e.State == state);
}

private PropertyInfo GetIsActiveProperty(DbEntityEntry entity)
{
return entity.Entity.GetType()。GetProperty(IsActive,BindingFlags.NonPublic | BindingFlags。实例| BindingFlags.Public);
}

当我删除根实体(像客户)这样很好,但是当我尝试删除一个小孩的实体,像是银行账户,我得到这个例外:


与CustomerBankAccounts AssociationSet在
中为已删除状态。给定多重约束,相应的
'BankAccount也必须在'已删除'状态。


我不确定为什么我得到这个错误。我只是更新我的银行帐户,而不是删除它。有人可以解释为什么我得到这个例外,我如何解决这个问题?

解决方案

当你打电话 BankAccount 以及 BankAccount 与其 >客户被标记为删除。



稍后更改 BankAccount EntityState.Modified 而不是删除它。然而,与客户的关系仍被标记为删除。



EntityFramework现在要提交更改并删除的关系。由于这是一个识别关系,因此预期一个 BankAccount 应该被删除,而不是这样。因此,错误消息。



要解决此问题,您需要设置关系不被删除。我现在没有准备好代码,但是我假设有相同的类,它的 GetEntitiesByState 方法也应该有一个 GetRelationshipsByState 或类似的东西。



这些关系还在 DbChangeTracker.Entries()列表。您将需要找出一种找到正确关系的方法,但您要保持的位置是您的其他检测代码( var property = this.GetIsActiveProperty(entity); 等)现在生活。


I have customers and bankaccounts. A customer can have multiple bankaccounts, but a bankaccount can have one customer.

I'm trying to remove a bankaccount by it's id. But when we remove things, we actually perform an update by setting the IsActive property to false.

My delete part looks like this:

var bankaccounts = from b in this.unitOfWork.BankAccounts
                    where command.Ids.Contains(b.Id) // command.ids is an array with id's
                    select b;

this.unitOfWork.BankAccounts.DeleteObject(bankaccounts);

Then, before the commit, we have this code that will convert the delete into an update and set the IsActive property to false

public void Commit()
{
    var addedEntities = this.GetEntitiesByState(EntityState.Added);
    foreach (var entity in addedEntities)
    {
        var property = this.GetIsActiveProperty(entity);
        property.SetValue(entity.Entity, true);
    }

    var deletedEntities = this.GetEntitiesByState(EntityState.Deleted);
    foreach (var entity in deletedEntities)
    {
        var property = this.GetIsActiveProperty(entity);
        if (property != null)
        {
            entity.State = EntityState.Modified;
            property.SetValue(entity.Entity, false);
        }
    }

    this.mapper.Commit();
}

private IEnumerable<DbEntityEntry> GetEntitiesByState(EntityState state)
{
    return this.context.ChangeTracker.Entries().Where(e => e.State == state);
}

private PropertyInfo GetIsActiveProperty(DbEntityEntry entity)
{
    return entity.Entity.GetType().GetProperty("IsActive", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
}

When I'm removing 'root' entities (like customer) this works well, but when I try to remove a 'child' entity, like bankaccount, I get this exception:

A relationship from the 'CustomerBankAccounts ' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'BankAccount ' must also in the 'Deleted' state.

I'm not sure whyI get this error. I'm just updating my bankaccount, not removing it. Can someone explain why I get this exception and how I can fix this?

解决方案

When you are calling DeleteObject both the BankAccount and the relationship between that BankAccount and its Customer are marked for deletion.

Later you change the state of the BankAccount to EntityState.Modified instead of deleting it. However, the relationship to the Customer is still marked for deletion.

EntityFramework now wants to commit the changes and delete the relationship. Since this is an identifying relationship it expects that a BankAccount should be deleted along with it which is not the case. Thus the error message.

To fix this you need to set the relationship not to be deleted. I don't have the code ready right now but I am assuming the same class that has the GetEntitiesByState method should also have a GetRelationshipsByState or something similar.

The relationships also have an entry in the DbChangeTracker.Entries() list. You will need to figure out a way to find the right relationship that you want to keep but the place to do it is where your other detection code (var property = this.GetIsActiveProperty(entity); etc.) lives right now.

这篇关于由于关联集,EF无法删除子对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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