【问题标题】:Violation of PRIMARY KEY constraint when published on Azure在 Azure 上发布时违反 PRIMARY KEY 约束
【发布时间】:2017-07-07 06:23:47
【问题描述】:

ASP 对特定 ID 产生违反 PRIMARY KEY 约束。 (我在代码中随机生成 ID,同时检查它们在数据库中不存在)。

当我在本地计算机(使用相同的 Azure 托管数据库)上调试此代码时,一切正常。当我在 Azure 上发布我的代码时,我得到了错误。奇怪的是,由错误产生的随机 ID 在我的数据库中不存在。

代码(我复制了一个带有新 ID 和新方案 ID 的药物列表):

        List<medication> l = db.medication.AsNoTracking().Where(x => x.scheme_ID == schemeID).ToList();
            foreach (medication m in l) {
                int id = generateUniqueMedicationID();
                m.ID = id;
                m.scheme_ID = newSchemeID;
                db.medication.Add(m);
            }
        db.SaveChanges();

generateUniqueMedicationID() 方法:

    private int generateUniqueMedicationID()
    {
        bool stop = true;
        int id = -1;
        while (stop)
        {
            Random r = new Random();
            id = r.Next(100000000, 1000000000);
            if (!db.medication.Any(o => o.ID == id)) stop = false;
        }
        return id;
    }

【问题讨论】:

  • SQL server的表中PK列是如何定义的?
  • generateUniqueMedicationID 看起来像什么?为什么不遵循标准 C# 命名约定?
  • 将你的表Primary Key设置为Identity(1,1),这样每次在表中添加一行时它就会自动递增。
  • 当数据库说你有主键违规时,你没有想过检查你生成的 ID 是否真的是唯一的吗?

标签: c# random primary-key


【解决方案1】:

C# 'Random' 方法不是真正的随机数生成器。正如微软所说,它是一个“伪随机数字生成器”。

这篇 MSDN 文章[https://msdn.microsoft.com/en-us/library/system.random(v=vs.110).aspx] 说:

伪随机数以相等的概率从有限的 一组数字。选择的数字不是完全随机的,因为 用数学算法来选择它们,.....

生成一个加密安全的随机数,例如一个 适合创建随机密码,使用 RNGCryptoServiceProvider 类或派生类 System.Security.Cryptography.RandomNumberGenerator。

简单来说,数字会在一定间隔后重复。

如果您使用的是 SQL Server 2012(或更高版本),则获得非连续 ID 值的最佳方法是更改​​您的 ID 列并使用生成 GUID 的 uniqueidentifier 类型,您应该让您的数据库引擎创建并分配值,而不是您的 C# 代码。

【讨论】:

  • 这是迄今为止最好和优雅的解决方案。供将来参考我的问题也可以通过以下方式解决:1)在循环外初始化随机数 - 或 - 2)在循环内调用 saveChanges() (根本没有效率)
猜你喜欢
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多