Entity framework 在保存时是否需要保存更改的Id?实体框架

Entity framework 在保存时是否需要保存更改的Id?实体框架,entity-framework,entity-framework-4,entity-framework-ctp5,Entity Framework,Entity Framework 4,Entity Framework Ctp5,我正在向数据库中插入一条记录,如下所示: class Transaction { int Id; } class TransactionUpdate { int StartingTransactionId; int EndingTransactionId; } 我想要的是,当我插入此对象时,我想创建另一条记录,如下所示: class Transaction { int Id; } class TransactionUpdate { int StartingTr

我正在向数据库中插入一条记录,如下所示:

class Transaction
{
   int Id;
}
class TransactionUpdate
{
   int StartingTransactionId;
   int EndingTransactionId;
}
我想要的是,当我插入此对象时,我想创建另一条记录,如下所示:

class Transaction
{
   int Id;
}
class TransactionUpdate
{
   int StartingTransactionId;
   int EndingTransactionId;
}
到目前为止,我在DbContext上的SaveChanges中有一个循环,它接受将要创建的新事务对象,创建TransactionUpdate对象,并将这些对象附加到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”,或者我当前插入的事务的Id

我怎样才能解决这个问题

非常感谢

已解决

我已经按照Ladislav的建议做了,现在正在创建一个要添加的项目列表,以及插入这些项目所需的对象的引用。因此:

    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();
        }
public override int SaveChanges()
{
var transactionUpdatesToAdd=新列表();
foreach(this.ChangeTracker.Entries()中的var条目)
{
if(entry.State==EntityState.Added)
{
var update=新事务更新();
update.StartingTransactionId=((Transaction)entry.Entity).PreviousTransactionId;
transactionUpdatesToAdd.Add(新元组(update,entry.Entity));
}
}
使用(var scope=new TransactionScope())
{
//保存新事务
base.SaveChanges();
//使用新ID更新TransactionUpdate
foreach(transactionUpdatesToAdd中的var updateData)
{
updateData.Item1.EndingTransactionId=updateData.Item2.Id;
this.TransactionUpdates.Add(updateData.Item1);
}
//插入新的TransactionUpdate实体。
返回base.SaveChanges();
}

如果您没有插入TransactionId,那么它仍然存在于您的对象中。将您的对象作为参数传递给重载方法SaveChanges,并使用它根据您的描述传递Id

我猜您在数据库中使用的是自动生成的Id。在对上下文执行
SaveChanges
之前,您不会收到此Id。Yo必须将操作分为两个单独的修改:

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
中,以执行整个原子操作保存。

我想避免这样做,我想知道EF中是否有可以挂接的事件?@James:没有,保存后没有事件。您可以在SaveChanges实现中触发自定义事件,但最终会得到相同的code.IMO如果不在应用程序中调用两次SaveChanges或生成ID,则无法执行此操作。没有理由避免调用两次SaveChanges,因为EF不支持命令批处理。