使用ExecuteStoreCommand插入记录后如何获取“新记录ID”(“INSERT

时间:2014-11-13 12:54:10

标签: sql-server asp.net-mvc linq asp.net-mvc-3 linq-to-entities

我正在使用MVC3,ASP.NET4.5,C#,EF5,SQL SERVER 2008 R2。

我希望了解插入记录后获取“新记录ID”的最佳方法,因为 PK是int32标识列

我目前的代码是:

db.ExecuteStoreCommand("INSERT INTO Table1(Col1,Col2 ) SELECT Col1,Col2 FROM Table1 WHERE Id =   {0}", myOldRecordId);
command = @"SELECT IDENT_CURRENT({0}) AS Current_Identity;";
myNewRecordId = (int)db.ExecuteStoreQuery<decimal>(command, "Table1").First();

虽然上述方法有效,但我担心的是其他人可以同时在同一个表中插入记录,因此检索到的NewRecordId =正确值+ 1。

一旦通过ExecuteStoreCommand发出“INSERT”,检索新NewRecordId的最佳方法是什么?

顺便说一下,出于多种原因,我需要使用原始DML,而不是通过EF进行POCO。

提前致谢。

修改

根据我对给出的建议的理解,代码会发生变化:

using(TransactionScope tran = new TransactionScope()) 
{
   db.ExecuteStoreCommand("INSERT INTO Table1(Col1,Col2 ) SELECT Col1,Col2 FROM Table1 WHERE Id =   {0}", myOldRecordId);
   command = @"SELECT SCOPE_IDENTITY ({0}) AS Current_Identity;";
   myNewRecordId = (int)db.ExecuteStoreQuery<decimal>(command, "Table1").First(); 
   tran.Complete();
}

我想我仍然需要更改它,以使“db.ExecuteStoreCommand”和“db.ExecuteStoreQuery”事务更明显。

EDIT2

经过更多的研究,我发现了这个:

db.Connection.Open(); //db = EF DBContext
var tran = db.Connection.BeginTransaction();

db.ExecuteStoreCommand("INSERT INTO Table1(Col1,Col2 ) SELECT Col1,Col2 FROM Table1 WHERE Id =   {0}", myOldRecordId);

command = @"SELECT SCOPE_IDENTITY ({0}) AS Current_Identity;";
myNewRecordId = (int)db.ExecuteStoreQuery<decimal>(command, "Table1").First(); 

tran.Commit();
db.Connection.Close();

请参阅:Reference

这是从其他用户记录插入中获取新ID而不会损坏的最佳方法吗?

实际上已经阅读了更多,这是旧的方式,“TransactionScope”是要走的路。

2 个答案:

答案 0 :(得分:1)

抱歉在答案而不是评论中写这个:我认为你99%是正确的,据我所知,你应该使用

scope_identity()

而不是ident_current,来到100%

答案 1 :(得分:1)

有关于获取最后一次插入ID here的答案。你应该使用这种方法。你得到的最后一个插入ID是每个会话。因此,您从工作会话中获取最后插入的ID。如果使用正确的方法,不应该有任何问题。

如果您插入一行并获取最后插入的ID,则执行新的SELECT,您可能会遇到已经预测到的问题。