2013-07-11 40 views
1

我有客户和银行帐户。客户可以有多个银行帐户,但银行帐户可以有一个客户。因为关联集,EF无法删除子对象

我试图通过它的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); 
} 

当我删除“根”实体(如客户)时,这很有效,但是当我尝试删除“子”实体时,例如bankaccount,我得到以下异常:

来自'CustomerBankAccounts'AssociationSet的关系在 '已删除'状态。由于多重性限制,相应的“BankAccount”也必须处于“已删除”状态。

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

+0

题外话:我发布了这个问题。可能是你可以回答它:http://stackoverflow.com/questions/17588993/ef-what-is-the-sql-output-when-using-contains-in-linq-query – mynkow

回答

2

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

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

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

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

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

+0

感谢您的解释。但是当我查看'DbChangeTracker.Entries()'列表时,我只能看到从中更改状态的bankaccount。该列表只有一个条目。 – Martijn

+0

我以为这是包含所有实体(包括关系)的列表。如果它不在那里,我不知道它现在在哪里。我记得编写代码检查'entry.Entity'是否为空,因为这是关系的情况。 – Chris

相关问题