2009-06-24 3 views
5

コンテキストを照会し、エンティティに変更を加え、コンテキストを再クエリし、セーブチェンジを実行せずに変更されたエンティティを含む結果セットを取得することは可能ですか? ? (私はロールバックしたいかもしれないのでsavechangesをしたくありません)クエリーエンティティフレームワークコミットされていないレコードを含む

私はGetObjectStateEntriesを使って変更を取り戻すことができますが、私は変更されたエンティティだけでなく、データセット全体に興味があります。

これを行う唯一の方法はsavechangesですが、私の条件が満たされていない場合はロールバックができるように、トランザクションスコープをすべて囲むことです。それとも、私は何か簡単に欠けていますか?

+0

正確に達成しようとしていることはありますか?コミットする前に新しいセットにアクセスする必要があるのはなぜですか?重複や挿入/変更されたエンティティとセット内の他のすべてのエンティティを比較する必要がある何か他のものを防ぐために何らかのバリデーションを行っていますか? – Merritt

+0

基本的にはyesです。コミットを防止したいのではなく、すべてのエンティティの現在の状態(変更されていない状態)の条件に基づいて別のエンティティを更新したいと考えています。ワークフローに似たビジネスルールです。残念ながら、状態は.savechanges()を呼び出さない(キャッシュされたコンテキストで)呼び出すさまざまなサービスで変更される可能性があります。したがって、これらの変化を追跡することは難しいです。 – itchi

+0

これは、別のサービス/アプリケーション(または少なくとも別のスレッド)が実行できる操作のように聞こえます。更新を処理するWindowsサービス(またはSQLジョブ)を作成できますか? SavingChanges()の前にやらなければならない理由はありますか? – Merritt

答えて

3

既存のエンティティのセットを追加するのはなぜですか?私はこれをテストし、それはそれが削除を考慮していないワーク・ようですが、あなたのアイデアを得ることができる必要があります:

// get the entities that have been inserted or modified 
var projects = myObjectContext.ObjectStateManager.GetObjectStateEntries(
    EntityState.Added | EntityState.Modified).Where(
      x => x.Entity is Project).Select(x=> (Project) x.Entity); 

// get existing entities, exclude those that are being modified 
var projects2 = myObjectContext.Projects.Where(
    BuildDoesntContainExpression<Project, int>(z => z.ProjectId, 
      projects.Select(x => x.ProjectId))); 

// Union the 2 sets 
var projects3 = projects.Union(projects2); 

BuildDoesntContainExpression:あなたが含まれているを使用し、したがって、あなたすることはできません何らかの理由でEFを使用することができないので、この方法を使用してください:

private static Expression<Func<TElement, bool>> BuildDoesntContainExpression<TElement, TValue>( 
     Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values) 
    {  
     if (null == valueSelector) 
     { 
      throw new ArgumentNullException("valueSelector"); 
     } 

     if (null == values) 
     { 
      throw new ArgumentNullException("values"); 
     }  

     ParameterExpression p = valueSelector.Parameters.Single();  

     // p => valueSelector(p) == values[0] || valueSelector(p) == ... 
     if (!values.Any())  
     {   
      return e => false;  
     }  

     var equals = values.Select(
      value => (Expression)Expression.NotEqual(valueSelector.Body, Expression.Constant(value, typeof(TValue))));  

     var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.And(accumulate, equal));  

     return Expression.Lambda<Func<TElement, bool>>(body, p); 
    } 
+0

ええ、私はこの種のアプローチも考えていました。簡単な方法はありませんか?私はこの質問がより一般的ではないことに驚いています。 – itchi

+0

これは技術的に機能するので、私はあなたに答えを与えています。しかし、私はより単純な方法があると確信しています。しかし、あなたはこれにいくつかの素晴らしい考えを入れて、ポイントに値する:)ありがとう! – itchi

関連する問題