22

对于具有标识的表:

    [AutoIncrement]
    public int Id { get; set;}

向数据库中插入新行时,检索对象 Id 的最佳方法是什么?

例如:

db.Insert<> (new User());

插入后Id的值为0,但在数据库中显然不是这样。我能看到的唯一可能性如下:

Id = (int)db.GetLastInsertId();

但是,我不相信这是一个安全的电话。如果同时发生 100 个插入,则可能会返回另一个插入的 Id。在 EF 中,当您执行插入操作时,会为您设置 ID。

有谁知道解决这个问题的最佳方法?

4

3 回答 3

29

在默认使用参数化查询的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);

以下是展示 OrmLite 新 API 的更多示例


对于 OrmLite v3

正确的调用是db.GetLastInsertId()SQL Server 引擎盖下的调用,例如调用SELECT SCOPE_IDENTITY(),它返回该连接的最后插入的 id 。

这是安全的,因为可能发生的所有其他并发插入都使用不同的数据库连接。为了让其他人使用相同的连接,需要将其处理并释放回池中。

于 2013-01-14T13:13:54.090 回答
2

您绝对应该使用工作单元模式,特别是在这种情况下,您将与数据库相关的代码包装在事务范围内。

在 ormLite 中,您可以通过 IDbCommand 和 IDbTransaction 实现这一点(参见此处的示例http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.OrmLite/ServiceStack.OrmLite.Tests/ShippersExample.cs )

查看代码,您会发现它会变得不那么神奇而更多地手动编码,但这是一种方式。

于 2013-01-14T12:58:44.117 回答
2

更新:如此处所示如果您使用的是 ServiceStack/ORMLite v4,则需要利用参数化查询来获取插入的 ID。例如:

var UserId = db.Insert<User>(new User(), selectIdentity: true);
于 2014-04-29T19:55:39.117 回答