如何在C#中生成随机Unqiue数字

pea*_*ace 5 .net c# sql-server

public int GenPurchaseOrderNum()
{
    Random random = new Random();
    _uniqueNum = random.Next(13287, 21439);
    return UniqueNum;
}
Run Code Online (Sandbox Code Playgroud)

我从数据库中的PONumber列中删除了唯一约束,因为员工只应在设置交易时生成PO#.否则,PO#将为0.

PO号用于具有唯一约束,这会强制员工在所有情况下生成PO,因此db不会抛出唯一约束错误.

由于我删除了唯一约束,任何报价都没有PO将带有0值.否则,为PO#生成唯一值.但是,我没有db中的唯一约束,这使我很难知道应用程序生成的PO#是否唯一.

我该怎么办?

我希望我的问题很清楚

Ste*_*ard 11

GUID在开销方面有点高.具体来说,听起来你需要一个人类可读的PO#号码,这使得GUID不切实际.我更倾向于使用以下场景.

  1. 删除字段上的任何NOT NULL约束.
  2. 有一个存储过程,用于创建新的PO,使PO#字段为NULL.Null在所描述的情况下是最合适的,因为在DB NULL的世界中意味着"未知"并且因为你实际上没有PO#,所以它是未知的.
  3. 使用在交易完成时更新字段的存储过程,以递增到下一个可用的PO编号.这将发生在服务器端,因此更新来自哪个客户端并不重要,它仍然是该表的唯一.然后,此存储过程可以将更新的结果集(如果需要)返回给客户端,以便他们可以看到新的PO#.

这是20公尺的视野.


Pan*_*hra 11

每次执行新的Random()时都会初始化.这意味着在紧密循环中,您可以多次获得相同的值.您应该保留一个Random实例并继续在同一个实例上使用Next.

//Function to get random number
private static readonly Random getrandom = new Random();
private static readonly object syncLock = new object();
public static int GetRandomNumber(int min, int max)
{
    lock(syncLock) { // synchronize
        return getrandom .Next(min, max);
    }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*isF 5

如果你真的想要一个随机值,而不是返回一个int你可以使用GUID.这些保证是独一无二的:

GUID是128位整数(16字节),可以在需要唯一标识符的所有计算机和网络中使用.这种标识符具有非常低的重复概率.

资源

另一种方法是记录最后使用的数字,并在每次需要新PO时简单地增加它.确保你锁定它,这样两个进程就不会尝试同时增加它.


Rem*_*anu 5

  • 不要将0用于未知值.添加唯一约束并使用NULL表示未知/未生成的值.如果您愿意,向用户显示NULL为0,但这与问题正交.
  • 不要使用随机生成唯一编号,然后尝试插入,您将不必要地重复逻辑重试和重新生成.使用序列生成器UPDATE seqnces SET sequence = sequence+1 OUTPUT INSERTED.sequence WHERE key = 'somekey'
  • 不要使用随机生成商业含义值,如采购订单编号.使用序列生成器,如上所述.

更新

使用SQL Server 2008及更高版本,您可以使用唯一的筛选索引作为不等于0的所有内容的约束:

create unique index idxTbaleUniquePoNumber 
 on <table> (po_number) 
 where (po_number > 0);
Run Code Online (Sandbox Code Playgroud)

有点像吃蛋糕和吃蛋糕......