2017-08-29 90 views
0

這是我在這個網站上的第一個問題。我在ASP.Net網絡應用程序中教授自己的MVC和實體框架。我有一系列相關的實體,當我調用context.saveChanges()時,刪除的相關數據項不會被刪除。我的實體 我有一個物品實體,可以有0到許多別名。這是數據庫第一個項目,大部分這些代碼行都是自動生成的。使用實體框架從數據庫中刪除相關對象

public Class Item 
{ 
    public int Id{get;set}; 
    public string Name {get;set;} 
    public virtual ICollection<AliasClass> AssociatedAliases {get;set;} 
} 

public Class AliasClass 
{ 
    public int Id {get;set;} 
    public int ItemId {get;set;} 
    public string AliasName {get;set;} 

    public virtual Item RelatedItem {get;set;} 
} 

好的,我們完成了自動生成的東西。我的回傳操作接受回發視圖模型。我正在實施存儲庫模式。而我的物品回購有更新功能。

[HttpPost] 
public ActionResult Edit (Models.EditViewPostBack MyPostBackModel) 
{ 
    If (!ModelState.isValid){ 
    ... rebuild and copy // this part works. Skipping over it 
    } 

    // this may be a key line of my issue 
    MyPostBackModel.Item.Alias = MyPostBackModel.myAliases; 
    ItemRepo.Update(MyPostBackModel.Item); 
    return RedirectToAction("Index","Home"); 
} 

這裏是Models.EditViewPostBack。新的關聯列表以數組形式傳回。新關聯的ID爲0.在更新時,它將被分配一個真實的ID。

public class EditViewPostBack{ 
     Item myItem {get; set;} 
     AliasClass[] myAliases {get;set;} 
    } 

現在,最後是項目的肉和我真正的問題。這是應該更新更改的ItemRepo中的方法。

public void Update (Item myItem) 
    { 

     // myItem.AssociatedAliases contains only the wanted associations. 
     // It doesn't have the to-be deleted items. 
     // new items have an id of 0 

     // defined in class constructor. 
     context.Item.Attach(myItem); 
     context.Entry(Item).State = EntityState.Modified; 
     foreach(var name in myItem.AssociatedAliases){ 
     // finds the modified local version of the item. doesn't connect 
     // to the database to location info. 
     if(name.id > 0) 
     { 
      var moded = context.AliasClass.find(name.Id); 
      context.Entry(moded).State = EntityState.Modified; 
     } 
     else 
     { 
      // it is brand new 
      context.Item.Add(name) 
     } 
     }   
     // 
     // Once the alias is not attached to it's item it has to go 
     // How to handle deletes goes here 
     // 
     context.SaveChanges(); 
    } 

因爲entitystate沒有被標記爲已刪除,所以關聯仍然存在,並且該項顯示爲我從未刪除它。我已經嘗試了幾件事情。

如果我使用context.Alias.linqFunction()加載或搜索原始項目,自ID匹配以來,整個列表將與myItem參數重新關聯。

// invoking the following line causes Item.Alias to fully re-associate. 
// I lose the list passed to the function 
context.AliasClass.Where(x=>x.ItemId == myItem.Id) 

,因爲這將是一個往返的地方,我不刪除的項目數據庫,我目前無法加載的別名。

我想我需要一種方法來刪除,除非Id匹配仍然連接的列表。但刪除需要刪除項目的一個實例。

怎樣才能從我的數據庫中刪除這些關聯的別名?

回答

0

您的問題是因爲有三種情況Aliases 。他們可能是新的或編輯或混合。因此,對於處理您首先需要處理Aliases變化超過Item分開做這個創造新Alias[],然後做到這一點:

foreach(var name in myItem.Aliases){ 
      if it is edited one: update it 
      if it is new one: save it with id of myItem 
      } 

然後更新myItem之前,只是把:

myItem.Aliases=null; 

如果你有一些刪除Aliases,你不能指望EF inelegance來處理刪除他們,就像你添加新的那樣。你需要自己刪除它們。 所以應該有類似

allAliases=context.Getall(Aliases).where(they are for current item); 

然後你就可以有

foreach(var aliase in allAliases){ 
     if it it isnot in myItem.Aliases: delete it 
     } 

爲了獲得更好的性能和更低的複雜性,我建議你先刪除數據庫中的所有Aliases,然後所有的myItem.Aliases會隨着新的。所以當你保存你的myItem時,所有相關的Aliases都會自動添加,你只需要兩次與db的交互,這意味着更好的性能。

+0

這不起作用。使myItem.Aliases null只刪除與項目的關聯,但不會將其從數據存儲中刪除。我需要別名不再與一個項目相關**獲取**刪除**。現在在Aliases表中有一個強制性的ItemId。但我確實看到了你在任何地方都使用別名/別名的觀點。我會更新我的問題以使用更好的名稱來防止混淆。 –

+0

@Michael我更新了我的答案。 – Hadee

+0

謝謝,Hadee。我之前嘗試過這樣的事情,但遇到了一個問題。您提出的解決方案將始終向數據庫發出2個請求。這對於更新過程似乎非常低效。我以前遇到的問題是,當我加載其中itemid是當前項目的別名時,項目和別名之間的所有先前存在的關係都會突然出現在item.aliasclass中。那麼我就會忽略需要添加,刪除或更新的內容。 –