Требование идентификатора из SaveChanges при сохранении? Entity Framework - PullRequest
0 голосов
/ 01 февраля 2011

Я вставляю запись в базу данных, которая выглядит следующим образом:

class Transaction
{
   int Id;
}

То, что я хочу, - это когда я вставляю этот объект, я хочу создать другую запись, например:

class TransactionUpdate
{
   int StartingTransactionId;
   int EndingTransactionId;
}

Что у меня есть, так это цикл в моих SaveChanges на DbContext, который принимает новые объекты транзакций, которые будут созданы, создает объекты 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);
     }
   }
 }

Проблема в том, что я не могу правильно создать TransactionUpdate, поскольку у меня нет 'EndingTransactionId' или идентификатора транзакции, которую я сейчас вставляю.

Как я могу решить эту проблему?

Большое спасибо.

решено

Я сделал то, что предложил Ладислав, и сейчас создаю список элементов для добавления вместе со ссылками на объекты, которые требуются длявставить их.Таким образом:

    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();
        }

Ответы [ 2 ]

1 голос
/ 01 февраля 2011

На основании вашего описания, я думаю, вы используете автоматически сгенерированный идентификатор в базе данных.Вы не получите этот идентификатор перед выполнением SaveChanges в контексте.Вы должны разделить операцию на две отдельные модификации:

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 голосов
/ 01 февраля 2011

Если вы не вставили TransactionId, он все равно есть в вашем объекте. Передайте ваш объект в качестве параметра перегруженному методу SaveChanges и используйте его для передачи идентификатора

...