【发布时间】:2014-11-13 12:54:09
【问题描述】:
我正在使用 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();
这是从其他用户记录插入中获取新 ID 且不损坏的最佳方式吗?
实际上已经阅读更多,这是旧方法,“TransactionScope”是要走的路。
【问题讨论】:
-
尝试使用
TransasctionScope,然后使用scope_identity() 类似using (TransactionScope scope = new TransactionScope(TransactionScopeOptions) { your code to get identity after insert } -
谢谢。我没有使用“TransactionScope”。任何代码示例的机会。只是有点困惑是 INSERT 和 SELECT 进入这个还是只是 SELECT?
-
你在使用
Entity Framework吗?请阅读一般 Web 应用程序中的并发问题以及.net框架如何与Entity等 ORM 一起处理它,正如 @Nilesh 提到的一种方法是使用事务...事务可以在数据库服务器级别也是...Google 是您最好的朋友... -
这两个语句都需要成为范围的一部分。只是示例代码,但没有 EF。
var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Test"].ConnectionString); conn.Open(); using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) { var cmd = new SqlCommand("Insert into tempforts values('1')", conn); cmd.ExecuteNonQuery(); cmd = new SqlCommand("Select scope_Identity()",conn); var id = cmd.ExecuteScalar(); } -
请参阅上面的编辑,了解我尝试的新代码,其中包含您的建议。
标签: sql-server asp.net-mvc linq asp.net-mvc-3 linq-to-entities