0

私はこのようになりますこれは、データベースにレコードを挿入しています:、私が欲しい保存中にSaveChangesのIDを要求していますか? Entity Frameworkの

class Transaction 
{ 
    int Id; 
} 

私は、このオブジェクトを挿入すると、私はこのような別のレコードを、作成したいです:

class TransactionUpdate 
{ 
    int StartingTransactionId; 
    int EndingTransactionId; 
} 

私がこれまで持っていたことは、DbContextのSaveChangesのループで、新しいTransactionオブジェクトが作成され、TransationUpdateオブジェクトが作成され、DbContextに接続されます。

public override int SaveChanges() 
{ 
    foreach(var entry in this.ChangeTracker.Entries()) 
    { 
    if(entry.Entity is Transaction) 
    { 
     var update = new TransactionUpdate(); 
     update.StartingTransactionId = ((Transaction)entry.Entity).PreviousTransactionId; 
     update.EndingTransactionId = ((Transaction)entry.Entity).Id; // This is zero because the entity has not been inserted. 
     this.TransactionUpdates.Add(update); 
    } 
    } 
} 

の問題は、私は現在挿入していますトランザクションのID「EndingTransactionId」私が持っていないので、私はきちんとTransactionUpdateを作成することはできません、である、または。

どのように私はこの問題を解決することができますか?

多くのありがとうございます。

は、私はラディスラフが提案し、ここでそれらを挿入するために必要とされているオブジェクトへの参照とともに、追加する項目のリストを作成していますどのように行われている

を解決しました。従って:

public override int SaveChanges() 
    { 
     var transactionUpdatesToAdd = new List<Tuple<TransactionUpdate, Transaction>>(); 

     foreach (var entry in this.ChangeTracker.Entries<Transaction>()) 
     { 
      if (entry.State == EntityState.Added) 
      { 
       var update = new TransactionUpdate(); 
       update.StartingTransactionId = ((Transaction)entry.Entity).PreviousTransactionId; 
       transactionUpdatesToAdd.Add(new Tuple<TransactionUpdate, Transaction>(update, entry.Entity)); 
      } 
     } 

     using(var scope = new TransactionScope()) 
     { 
     // Save new Transactions 
     base.SaveChanges(); 

     // Update TransactionUpdates with new IDs 
     foreach (var updateData in transactionUpdatesToAdd) 
     { 
      updateData.Item1.EndingTransactionId = updateData.Item2.Id; 
      this.TransactionUpdates.Add(updateData.Item1); 
     } 

     // Insert the new TransactionUpdate entities. 
     return base.SaveChanges(); 
     } 

答えて

1

あなたの説明に基づいて、データベースで自動生成されたIDを使用していると思います。あなたはコンテキスト上でSaveChangesを実行しているこのId befereを受け取ることはありません。次の2つの別々の修正に操作を分割する必要があります。

public override int SaveChanges() 
{ 
    // call base context saving operation to insert all Transactions 
    base.SaveChanges(); 

    foreach(var entry in this.ChangeTracker.Entries())  
    {  
     if(entry.Entity is Transaction)  
     {   
     var update = new TransactionUpdate();   
     update.StartingTransactionId = ((Transaction)entry.Entity).PreviousTransactionId;   
     update.EndingTransactionId = ((Transaction)entry.Entity).Id;  
     this.TransactionUpdates.Add(update);  
     }  
    } 

    // save changes again to insert all TransactionUpdates 
    base.SaveChanges(); 
} 

あなたはアトミック操作として、全省を実行するためにTransactionScopeにそれをラップする必要があります。

+0

私はこれをやるのを避けたいと思っていましたが、私はEFの中にフックできるイベントがあるのか​​疑問に思いましたか? – James

+0

@James:いいえ保存してもイベントはありません。 SaveChanges実装でカスタムイベントを発生させることはできますが、同じコードで終了します。 IMOには、SaveChangesを2回呼び出すことなく、またはアプリケーションでIDを生成せずに行う方法はありません。 EFがコマンドのバッチ処理をサポートしていないため、SaveChangesを2回呼び出すことを避ける理由はありません。 –

0

あなたがあなたのオブジェクトにとにかく持っていれば、あなたはそれを持っています。オブジェクトをパラメータとしてオーバーロードされたメソッドSaveChangesに渡して、それを使ってIDを渡します。

+0

申し訳ありませんが、私はそれを理解していませんでした... – James

関連する問題