由于关联集,EF无法删除子对象

时间:2013-07-11 08:32:09

标签: c# entity-framework

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

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

我的删除部分如下所示:

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);

然后,在提交之前,我们有这个代码将删除转换为更新并将IsActive属性设置为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);
}

当我删除'root'实体(比如客户)时,这很有效,但是当我尝试删除'child'实体时,例如bankaccount,我得到了这个例外:

  

来自'CustomerBankAccounts'AssociationSet的关系在   '已删除'状态。给定多重约束,相应的   'BankAccount'也必须处于'已删除'状态。

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

1 个答案:

答案 0 :(得分:2)

当您致电DeleteObject时,BankAccountBankAccount及其Customer之间的关系都会被标记为删除。

稍后您将BankAccount的状态更改为EntityState.Modified,而不是删除它。但是,与Customer的关系仍标记为删除。

EntityFramework现在想要提交更改并删除关系。由于这是一种识别关系,因此预计应该删除BankAccount,而不是这种情况。因此错误信息。

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

关系在DbChangeTracker.Entries()列表中也有一个条目。您需要找到一种方法来找到您想要保留的正确关系,但是这样做的地方就是您的其他检测代码(var property = this.GetIsActiveProperty(entity);等)现在所在的位置。

相关问题