对于具有标识的表:
[AutoIncrement]
public int Id { get; set;}
在数据库中插入新行时,检索对象ID的最佳方法是什么?
例如:
db.Insert<> (新用户());
插入后Id的值为0,但在数据库中显然不是这种情况。我能看到的唯一可能性如下:
Id = (int)db.GetLastInsertId();
但是我不相信这是一个安全的电话。如果同时发生100个插入,则可能会返回另一个插入的Id。在EF中进行插入时,会为您设置ID。
有谁知道最好的方法吗?
答案 0 :(得分:28)
在 ServiceStack.OrmLite v4 中默认使用参数化查询,db.Save()
中有几个选项会自动填充AutoIncrement Id,例如:
db.Save(item);
item.Id //populated with the auto-incremented id
否则,您可以使用以下方法选择最后一个插入ID:
var itemId = db.Insert(item, selectIdentity:true);
以下是more examples showcasing OrmLite's new API's。
对于OrmLite v3
正确的呼叫是db.GetLastInsertId()
,对于SQL Server而言,例如呼叫SELECT SCOPE_IDENTITY(),它返回连接的最后一个插入ID。
这是安全的,因为可能发生的所有其他并发插入都使用不同的DB连接。为了让其他人使用相同的连接,需要将其丢弃并释放回池中。
答案 1 :(得分:2)
您绝对应该使用工作单元模式,尤其是在此方案中,您将db相关代码包装在事务范围中。
在ormLite中,您可以通过IDbCommand和IDbTransaction实现此功能(请参阅此处的示例http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.OrmLite/ServiceStack.OrmLite.Tests/ShippersExample.cs)
看一下代码,你会发现它不那么神奇,而且手动编码更多,但它是单向的。
答案 2 :(得分:2)
更新:如here所示,如果您使用的是ServiceStack / ORMLite v4,则需要使用参数化查询来获取插入的ID。例如:
var UserId = db.Insert<User>(new User(), selectIdentity: true);