2017-10-18 9 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>(); 
    } 
} 

基本的な考え方は、すべてのユーザーに1つのキャンペーンを割り当てることです。ユーザーが割り当てたキャンペーンを削除すると:

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

このキャンペーンに割り当てられたユーザーも削除されます。私が望むのは、ユーザーを削除しないで、最初の利用可能なキャンペーンに割り当てるか、またはnullにすることです。私はエラーを取得していますので

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メソッドにオブジェクトのどのような種類を渡すのですか? 私はそれがあなたのエンティティのフレームワークプロキシモデルの1つだと思います。これは、別のデータベースコンテキストによって照会されました。 あなたのfor-loopでリンクされたユーザオブジェクトにアクセスしましたが、コンテキストがもう存在しないため読み込めませんでした。

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

異なるデータベースコンテキストのオブジェクトを混在させないでください。

キャンペーンのIDをDeleteCampaignメソッドに渡すと、新しいデータベースコンテキストでキャンペーンをクエリする必要があります。 その後、1つの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)UserクラスのCampaignIdをnullにします。それ以外の場合は、外部キーがNULL可能ではないため、キャンペーンなしのユーザーを持つことはできません。

public int? CampaignId {get; set;} 

これでコードが機能します。

関連する問題