Nhibernate 标准:“选择 max(id)...”
我可以使用 Criteria 执行 t-sql 命令来选择表中列的最大值吗?
'从客户中选择@cus_id = max(id) + 1'
Ta
Ollie
Can I use a Criteria to execute a t-sql command to select the max value for a column in a table?
'select @cus_id = max(id) + 1 from customers'
Ta
Ollie
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用投影:
Use Projection:
Max(id) + 1 是一种非常糟糕的生成 id 的方法。 如果这是您的目标,请寻找另一种生成 id 的方法。
编辑:回答 LnDCobra:
这很糟糕,因为很难确保插入时得到的 max(id) 仍然是 max(id) 。 如果另一个进程插入一行,您的插入将具有相同的 id,并且您的插入将失败。 (或者,相反,如果您的插入先发生,则其他进程的插入将失败。)
为了防止这种情况,您必须阻止任何其他插入/使您的获取和后续插入原子化,这通常意味着锁定表,这会损害性能。
如果您只锁定写入,则其他进程将获得 max(id),这与您获得的 max(id) 相同。 您执行插入并释放锁,它会插入重复的 id 并且失败。 或者它也尝试锁定,在这种情况下它会等待你。 如果你也锁定防止读取,那么每个人都会等待你。 如果它也锁定写入,那么它不会插入重复的 id,但它会等待您的读取和写入。
(它破坏了封装:您应该让 RDBMS 找出它的 ID,而不是连接到它的客户端程序。)
通常,此策略将:
* 中断
* 需要一堆“管道”代码才能使其工作
* 显着降低性能
* 或全部三者
,与仅使用 RDBMS 的内置序列或生成的自动增量 id 相比,它会更慢、更不稳健,并且需要更难维护代码。
Max(id) + 1 is a very bad way to generate ids. If that's your goal, find another way to generate ids.
Edit: in answer to LnDCobra:
it's bad because it's hard to make sure that the max(id) you got is still the max(id) when you do the insert. If another process inserts a row, your insert will have the same id, and your insert will fail. (Or, conversely, the other process's insert will fail if your insert happened first.)
To prevent this, you have to prevent any other inserts/make your get and subsequent insert atomic, which generally means locking the table, which will hurt performance.
If you only lock against writes, the other process gets max(id), which is the same max(id) you got. You do your insert and release the lock, it inserts a duplicate id and fails. Or it tries to lock too, in which case it waits on you. If you lock against reads too, everybody waits on you. If it locks against writes also, then it doesn't insert the duplicate id, but it does wait on your read and your write.
(And it breaks encapsulation: you should let the rdbms figure out its ids, not the client programs that connect to it.)
Generally, this strategy will either:
* break
* require a bunch of "plumbing" code to make it work
* significantly reduce performance
* or all three
and it will be slower, less robust, and require more hard to maintain code than just using the RDBMS's built in sequences or generated autoincrement ids.
最好的方法是制作额外的序列表。
您可以在其中维护序列目标和值。
OwnerId - 当您需要基于某种所有者为同一实体维护不同的序列时。 例如,您需要维护合同内文档的编号,则
OwnerId 将 = ContractId
Best approach is to make additional Sequences table.
Where you can maintain sequence target and value.
OwnerId - when you need to maintain different sequences for same entity, based on some kind of owner. For example you need to maintain numbering for document within contract, then
OwnerId will be = contractId