2013-07-11 38 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

相關問題