我正在使用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”是要走的路。
答案 0 :(得分:1)
抱歉在答案而不是评论中写这个:我认为你99%是正确的,据我所知,你应该使用
scope_identity()
而不是ident_current,来到100%
答案 1 :(得分:1)
有关于获取最后一次插入ID here的答案。你应该使用这种方法。你得到的最后一个插入ID是每个会话。因此,您从工作会话中获取最后插入的ID。如果使用正确的方法,不应该有任何问题。
如果您插入一行并获取最后插入的ID,则执行新的SELECT,您可能会遇到已经预测到的问题。