San*_*osh 17 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; }
}
Run Code Online (Sandbox Code Playgroud)
的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);
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
[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();
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,所有这些代码都运行良好,除了偶然跳过近1000个数字的大间隙的标识值.
有人遇到过这样的问题吗?请分享你的想法.
Ben*_*man 19
如果你需要消除这些差距,你可能在这里运气不好.
我在开发/测试新应用程序时自己也遇到过这个问题.我根据我读到的有关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个块.有关更多文档,请参见此处
如果这成为一个问题,那么Identity列似乎已被更改为使用相同的范例.因此,当您的服务器,或者在这种情况下您的sql azure实例重新启动时,您可以在标识列中获得较大的间隙(1000),因为它将大块缓存为"已使用".对于sql server 2012,有一个解决方案.您可以指定启动标志t272以将您的身份恢复为使用旧的sql server 2008 r2范例.问题是我不知道(可能不可能)如何在sql Azure中指定它.找不到文档. 有关sql server 2012的更多详细信息,请参阅此主题.
在msdn中查看身份文档.特别是"服务器重启或其他故障后的连续值"部分.这是它说的:
服务器重新启动或其他故障后的连续值 -出于性能原因,SQL Server可能会缓存标识值,并且在数据库故障或服务器重新启动期间,某些分配的值可能会丢失.这可能导致插入时身份值的缺口.如果间隙不可接受,则应用程序应使用带有NOCACHE选项的序列生成器,或使用自己的机制生成键值.
因此,如果您需要具有连续值,则可以尝试使用nocache指定序列,而不是依赖于您的标识列.我自己没试过,但听起来你在使用实体框架时遇到麻烦.
很抱歉,如果这没有多大帮助,但至少它是您的体验的一些信息.
| 归档时间: |
|
| 查看次数: |
6160 次 |
| 最近记录: |