我们说我有2个输入:Length
和Outcome
。
我的表单包含Short
和Long
的这两个输入,作为Length
的{{1}}和Success
及Failure
的值。
我想生成一个遵循此模式的Outcome
示例:
{Length}{Outcome}{auto-increment-int-padded-to-5-digits}
目前,我正在生成此ID:
SF00001
SF00002
LF00001
LS00001
LF00002
虽然这种方法有效,但我并不喜欢它。通过大量查询,无法保证生成的ID在插入时是正确的。这里的最佳做法是什么?
不幸的是,ID模式是规范的一部分,也是必需的。
编辑:错误信息:ID模式是要求的一部分,但不是100%"要求"成为一把钥匙。它应该真正读到这个模式需要成为表的一部分,因为它被其他应用程序用作它们的约定的一部分。
答案 0 :(得分:0)
如果问题是你遇到竞争条件,即生成重复密钥,那么你需要考虑像@Evk在他的评论中所说的那样原子地进行。
这意味着只允许同时生成1个ID。
您可以通过多种方式完成此操作。
首先是快速简单但不是很有前途的天真方式。 IFF只有一个生成ID的进程,在ID生成代码周围放置一个静态锁。例如:
static object _lock = new object();
private string NewId(string length, string outcome)
{
lock (_lock)
{
// make the id
}
}
这只有在这是唯一制作ID的过程时才有效。因此,如果您有> 1个流程,或者您计划将来,那么这不是一个好计划。
其次是让数据库控制原子性。这是' propper'办法。
我个人认为这是一个存储过程而不是EF。
此外,因为它将锁定您正在生成ID的表,您可能需要一个新表,其中只存储4行(每个长度/结果组合为1),并在每个行中生成下一个ID。
您可以预先对表格进行初始化,只在其中放入4行,每个行的下一个ID设置为0。
存储过程取决于您的数据库,但取决于伪代码:
begin tran
update id_table set next_id = next_id + 1 where lenght = the_length and success = the_success;
select next_id from id_table where lenght = the_length and success = the_success;
end tran