2011-11-08 3 views
0

私はこのような方法があります:commit = falseEntity Framework、この問題を回避するにはどうすればよいですか?

事があれば、私は私が知っているように、このメソッドを期待、であると私は、(たとえば上向きに80回の)ループで繰り返しこのメソッドを呼び出す

public FbUser FindUserByGraphOrInsert(dynamic json, bool commit = false) 
    { 
     string graphId = json.id; 

     EntityDataModelContext context = DataContext.GetDataContext(); 
     FbUser user = context.FbUsers.FirstOrDefault(u => u.FbGraphId == graphId); 

     if (user == null) 
     { 
      user = new FbUser(); 
      user.FbGraphId = json.id; 
      user.FbUsername = StringExtensions.UnicodeDecode(json.name); 

      context.FbUsers.AddObject(user); 

      if (commit) 
       context.SaveChanges(); 
     } 

     return user; 
    } 

をユーザーは既にコンテキスト内にありますが、これは当てはまりません。

最終的に変更を保存すると、80人のユーザーのリストが表示されます。ここでは27人が区別されます。

私はこのメソッドがそれらの27を返すと期待していますが、これを達成するためにどうすれば変更できますか?
本当に毎回変更を保存する必要がありますか?

+0

コンテキスト選択の最後にdistict()を使用してみましたか? –

+0

どういう意味ですか? – bevacqua

+0

これを保存する前に、実際にリストに追加した後、.Distinct()を使用してリストから別の要素をすべて取得すると、リストから別個の要素のみを取得し、明確な要素。 –

答えて

0

、私が働いていた次の拡張メソッドを実装しました。

public static IEnumerable<T> IncludeUnsaved<T>(this ObjectSet<T> set) where T : class 
    { 
     var addedObjects = set.Context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added); 
     var equalObjects = addedObjects.Select(e => e.Entity).OfType<T>(); 

     return equalObjects.Concat(set); 
    } 
2

あなたは単純にそうすることはできません。問題は、EFがあなたに同じデータをクエリするか、データベースに根本的な変更がないことを知る方法がないため、デフォルトでは常に各クエリがデータベースにヒットすることですあなたは接続を開いた。

しかし、ChangeTracker/ObjectStateManagerで既存の変更されたオブジェクトを確認し、新しいオブジェクトの追加を決定する前にそのオブジェクトを照会することもできます。

サンプル:政体の答えに基づいて

var addedObjects = context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added); 
var equalObjects = addedObjects.OfType<MyEntity>().Where(x => x.Name == newObject.Name); 
+0

これを行うには、毎回インスタンス化するのではなく、単一のコンテキストを使用して渡す必要があります。どのIDが既に追加されているのかを確認する方法は、このメソッドの外に 'List 'をそのまま維持し、追加する前にIDが含まれているかどうかを確認するだけです。 –

+0

私は単一のコンテキストを使用します。これが 'DataContext.GetDataContext()'の動​​作です。 – bevacqua

+0

@Nico - 単一のデータコンテキストを共有するといくつかの問題が発生する可能性があることに注意してください。 EFは単に共有されることはなく、開かれ、特定のものに使用され、閉鎖されます。データを共有するために、リポジトリのように中間のレイヤーを使用することができます。オートシェイプの場合は、トランザクションに戻すことができます – Polity

関連する問題