sql-server - Windows Azure SQL数据库-“身份自动增加”列会跳过值

标签 sql-server entity-framework asp.net-mvc-4 entity-framework-5 azure-sql-database

当前正在使用Entity Framework 5开发ASP.Net MVC 4应用程序。在初始开发阶段使用了CodeFirst。但是现在已经禁用了自动迁移功能,并直接使用SSMS和编写POCO来设计新表。一切都很好。

最近,在生产中发现了一个奇怪的问题。最初设计的表之一中的记录使自动递增标识值跳过了900多个数字。在过去3个月中,这已经发生3次。在本地调试应用程序,但无法复制。没有观察到任何模式或趋势。

型号:

public class Enquiry
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public Int64 EnquiryId { get; set; }

    [Required]
    public int UserId { get; set; }

    [Required]
    public byte Bid { get; set; }

    ...

    [Required]
    public DateTime Created { get; set; }

    [Required]
    public DateTime Modified { get; set; }
}

public class EnquiryDetail
{
    [Key]
    public Int64 EnquiryId { get; set; }

    [Required]
    public int CreditScore { get; set; }

    [Required]
    public byte BidMode { get; set; }

    public virtual Enquiry Enquiry { get; set; }
}

DBContext:
public class EscrowDb : DbContext
{

    public EscrowDb()
        : base("name=DefaultConnection")
    {

    }
    public DbSet<Enquiry> Enquiries { get; set; }
    public DbSet<EnquiryDetail> EnquiryDetails { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Entity<EnquiryDetail>()
            .HasRequired<Enquiry>(ed => ed.Enquiry)
            .WithRequiredDependent(e => e.EnquiryDetail);
    }
}

Controller :
[Authorize]
public class EnquiryController : Controller
{
    private EscrowDb _db = new EscrowDb();

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(EnquiryViewModel core)
    {
       var enquiry = new Enquiry();
       // Some code to set properties using passed ViewModel
       ...

       var enquiryDetail = new EnquiryDetail();
       // Some code to set properties using passed ViewModel
       ...

       enquiry.EnquiryDetail = enquiryDetail;

       _db.Enquiries.Add(enquiry);
       _db.SaveChanges();
    }
}

到目前为止,所有这些代码都能正常工作,除了标识值偶尔会被几乎1000个数字的大间隙跳过。

有人遇到过这种问题吗?请分享您的想法。

最佳答案

如果您需要消除这些差距,那么您可能不走运。

在开发/测试新应用程序时,我自己遇到了这个问题。我根据对sql server 2012的了解来了解sql azure中的情况。我无法找到有关sql azure的任何文档。

从我阅读的内容来看,这是IMO的一个错误。在Sql Server 2012中,Microsoft添加了创建序列的功能。序列记录以1000个块为单位使用的值。因此,假设您的序列正在执行中……1,2,3,4,5 ...,然后sql server重新启动。好了,该序列已经保存了以下事实:块1-1000已经被使用过,因此它将跳转到下一个1000...。因此,下一个值为1001、1002、1003、1004...。在使用序列时插入,但会导致异常的间隔。您的序列有一个解决方案。指定序列时,请添加“NOCACHE”参数,以免一次不保存1000个块。 See here for more documentation.

这成为一个问题的地方是,标识列似乎已更改为使用相同的范例。因此,当您的服务器(或在这种情况下,您的sql azure实例)重新启动时,您的标识列可能会出现较大的间隙(1000),因为它会将大型块缓存为“已用”。 sql server 2012对此有一个解决方案。您可以指定启动标志t272以将您的身份恢复为使用旧的sql server 2008 r2范例。问题是我不知道(可能不可能)如何在sql Azure中指定它。找不到文档。 See this thread for more details on sql server 2012.

Check the documentation of identity here in the msdn.特别是“服务器重新启动或其他故障后的连续值”部分。它说的是:

Consecutive values after server restart or other failures –SQL Server might cache identity values for performance reasons and some of the assigned values can be lost during a database failure or server restart. This can result in gaps in the identity value upon insert. If gaps are not acceptable then the application should use a sequence generator with the NOCACHE option or use their own mechanism to generate key values.



因此,如果您需要连续的值,则可以尝试使用nocache指定一个序列,而不要依赖您的身分列。自己还没有尝试过,but sounds like you'll have trouble getting this to work with entity framework.

抱歉,如果这样做没有太大帮助,但至少是有关您的经验的一些信息。

关于sql-server - Windows Azure SQL数据库-“身份自动增加”列会跳过值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17012339/

相关文章:

sql - 检查一个或多个 id 是否在 json 字符串中

sql-server - 相当于 MySQL SOURCE 命令来加载 SQL 脚本吗?

python - 将 MSSQL 与 AWS Lambda 结合使用

.net - 如何在 Entity Framework 中查找最后插入行的标识?

entity-framework - Azure Hadoop 和 Entity Framework

c# - asp.net MVC 路由顺序

mysql - SQL 语句语法差异

asp.net-mvc - 使用 ASP.NET MVC 和 Entity Framework 时,app.config 是必需的吗?

c# - MVC 4's mapRoute URL -- {controller}/{action} vs Controller/{action}. What' 的区别?

c# - 将 ASP.NET MVC 5 从 .NET 4.5 降级到 4.0