如何在 ServiceStack OrmLite 中检索自动递增的 ID?

Posted

技术标签:

【中文标题】如何在 ServiceStack OrmLite 中检索自动递增的 ID?【英文标题】:How to retrieve auto-incremented Id in ServiceStack OrmLite? 【发布时间】:2012-12-27 15:11:31 【问题描述】:

对于具有标识的表:

    [AutoIncrement]
    public int Id  get; set;

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

例如:

db.Insert (new User());

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

Id = (int)db.GetLastInsertId();

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

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

【问题讨论】:

【参考方案1】:

在默认使用参数化查询的 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(),例如在后台调用SELECT SCOPE_IDENTITY(),它返回该连接的最后插入的ID。

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

【讨论】:

哦,这是每个连接!现在这更有意义了。 感谢您对 v3 的澄清! db.GetLastInsertId() 似乎不起作用,因为它是我认为的隐藏方法....任何指针?【参考方案2】:

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

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

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

【讨论】:

将阅读有关 Unit of Work 并查看示例源代码。【参考方案3】:

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

var UserId = db.Insert<User>(new User(), selectIdentity: true);

【讨论】:

以上是关于如何在 ServiceStack OrmLite 中检索自动递增的 ID?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ServiceStack OrmLite 中检索自动递增的 ID?

ServiceStack.OrmLite 调用存储过程

如何解决 ServiceStack OrmLite 的七个连接表的限制

ServiceStack Webhook + ServiceStack.Webhooks.OrmLite 订阅商店插件问题

在运行时在 ServiceStack.OrmLite 中获取类的表名/避免硬编码表名

OrmLite(ServiceStack):仅使用临时数据库连接(使用“使用”?)