由于关联集,EF无法删除子对象 [英] EF cannot delete child object because of associationset
问题描述
我正在尝试通过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屋!