entity framework – 在事务中的“SaveChanges”之前检索ID

在entity framework中 – 在调用“SaveChanges”之前,有没有办法在事务中检索新创build的ID(标识)?

我需要第二次插入的ID,但它总是返回为0 …

ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext; objectContext.Connection.Open(); using (var transaction = objectContext.Connection.BeginTransaction()) { foreach (tblTest entity in saveItems) { this.context.Entry(entity).State = System.Data.EntityState.Added; this.context.Set<tblTest>().Add(entity); int testId = entity.TestID; .... Add another item using testId } try { context.SaveChanges(); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); objectContext.Connection.Close(); throw ex; } } objectContext.Connection.Close(); 

在将行插入到表中之后,由数据库生成ID。 在插入行之前,您不能问数据库该值是什么。

你有两种方法 – 最简单的方法就是调用SaveChanges 。 既然你是在一个交易中,你可以回滚,以防万一在你得到这个ID后出现问题。

第二种方法不是使用数据库内置的IDENTITY字段,而是自己实现它们。 当你有很多的批量插入操作时,这可能是非常有用的,但它带有一个价格 – 实现并不是微不足道的。

编辑:SQL Server 2012有一个内置的SEQUENCEtypes,可以使用,而不是一个IDENTITY列,不需要自己实现它。

@zmbq是正确的,你只能在调用保存更改后才能得到id。

我的build议是,你不应该依赖数据库的生成的ID。 数据库应该只是你的应用程序的一个细节,而不是一个整体和不可改变的部分。

如果你不能解决这个问题,请使用GUID作为标识符,因为它是唯一的。 MSSQL支持GUID作为本地列types,并且速度很快(虽然不比INT快)。

干杯

如果您的tblTest实体连接到您要附加的其他实体,则不需要使用Id来创build关系。 比方说tblTest附加到另一个Test对象,它在另一个Test对象中有tblTest对象和tblTestId属性,在这种情况下,你可以有这样的代码:

 using (var transaction = objectContext.Connection.BeginTransaction()) { foreach (tblTest entity in saveItems) { this.context.Entry(entity).State = System.Data.EntityState.Added; this.context.Set<tblTest>().Add(entity); anotherTest.tblTest = entity; .... } } 

提交后,关系将被创build,你不需要担心ID等。