根据模式生成递增ID

时间:2017-10-24 15:57:57

标签: c# .net sql-server entity-framework

我们说我有2个输入:LengthOutcome

我的表单包含ShortLong的这两个输入,作为Length的{​​{1}}和SuccessFailure的值。

我想生成一个遵循此模式的Outcome

示例:

{Length}{Outcome}{auto-increment-int-padded-to-5-digits}

目前,我正在生成此ID:

SF00001
SF00002
LF00001
LS00001
LF00002

虽然这种方法有效,但我并不喜欢它。通过大量查询,无法保证生成的ID在插入时是正确的。这里的最佳做法是什么?

不幸的是,ID模式是规范的一部分,也是必需的。

编辑:错误信息:ID模式是要求的一部分,但不是100%"要求"成为一把钥匙。它应该真正读到这个模式需要成为表的一部分,因为它被其他应用程序用作它们的约定的一部分。

1 个答案:

答案 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