2017-10-18 86 views
0

我正在做代碼第一個實體框架數據庫模型,而我正在拼湊級聯刪除。有我的簡單類:設置爲默認,而不是刪除級聯

public class User { 
    [Key()] 
    public int Id {get; set;} 
    public string Name {get; set;} 

    public int CampaignId {get; set;} 
    [ForeignKey("CampaignId")] 
    public virtual Campaign Campaign {get; set;} 
} 

public class Campaign { 
    [Key()] 
    public int Id {get; set;} 
    public string Description {get; set;} 

    public virtual List<User> Users {get; set;} 

    public Campaign() { 
     Users = new List<User>(); 
    } 
} 

基本的想法是分配一個活動給每個用戶。當我刪除用戶分配的廣告系列時:

internal static void DeleteCampaign(Campaign campaignToDelete) { 
      using (var context = new DatabaseContext()) { 
       context.Entry(campaignToDelete).State = EntityState.Deleted; 
       context.SaveChanges(); 
      } 
     } 

分配給該廣告系列的用戶也被刪除。我想要的是不刪除用戶,但將其分配到第一個可用的廣告系列,或者爲空。出於某種原因,我不能做這樣的事情:

internal static void DeleteCampaign(Campaign campaignToDelete) { 
      using (var context = new DatabaseContext()) { 

       for (int i = 0; i < campaignToDelete.Users.Count; i++) { 
        campaignToDelete.Users[i].Campaign = context.Campaigns.ElementAt(0); 
       } 

       context.Entry(campaignToDelete).State = System.Data.Entity.EntityState.Deleted; 
       context.SaveChanges(); 
      } 
     } 

因爲我得到錯誤:

An unhandled exception of type 'System.ObjectDisposedException' occurred in EntityFramework.dll 

Additional information: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. 

所以,我怎麼能避免呢?

+0

你是否啓用了延遲加載? – Coding

回答

0

1)你傳遞給DeleteCampaign方法是什麼樣的對象? 我認爲這是您的實體框架代理模型之一,它被另一個數據庫上下文查詢。 您在for循環中訪問鏈接的用戶對象,由於上下文不再存在,所以無法加載該對象。

for (int i = 0; i < campaignToDelete.Users.Count; i++) { 

不要混合不同數據庫上下文的對象。

更好的方法是,您將Campaign的ID傳遞給DeleteCampaign方法,然後您必須在新數據庫上下文中查詢該活動。 之後,您可以在一個using語句(=相同的數據庫上下文)中執行所有操作。

static void DeleteCampaign(int idOfCampaignToDelete) 
    { 
     using (var context = new DatabaseContext()) 
     { 
      var campaignToDelete = context.Campaigns.FirstOrDefault(c => c.Id == idOfCampaignToDelete); 
      for (int i = 0; i < campaignToDelete.Users.Count; i++) 
      { 
       campaignToDelete.Users[i].Campaign = context.Campaigns.ElementAt(0); 
      } 

      context.Entry(campaignToDelete).State = System.Data.Entity.EntityState.Deleted; 
      context.SaveChanges(); 
     } 
    } 

2)您不能在LINQ to Entities查詢中使用ElementAt(0)。 使用.FirstOrDefault()。

campaignToDelete.Users[i].Campaign = context.Campaign.FirstOrDefault(); 

3)使用戶類中的CampaignId可爲空。否則,您不能讓沒有廣告系列的用戶訪問,因爲外鍵不會爲空。

public int? CampaignId {get; set;} 

現在你的代碼應該工作。