为什么我在插入这些记录时会遇到主键违规? (EF4 Code-First)

时间:2011-02-20 20:53:09

标签: c# entity-framework entity-framework-4 code-first

我有以下实体

public class DocumentHistory
{
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime DateModified { get; set; }
    public User ModifiedbyUser { get; set; }
    public string HistoryAction { get; set; }

    public virtual int DocumentId { get; set; }
    public virtual Document Document { get; set; }
}

在我的DbContext中,我使用以下方式定义键:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // DocumentHistory properties
        modelBuilder.Entity<DocumentHistory>()
                    .HasKey(x => new { x.DocumentId, x.DateModified });   
    }

在我的自动化集成测试中,我使用

初始化一条记录
_doc.HistoryRecords.Add(new DocumentHistory { DateModified = DateTime.Now });

然后我尝试通过以下方式创建新记录:

        // Create the history record
        var history = new DocumentHistory
        {
            Name = doc.Name,
            Description = doc.Description,
            DateModified = DateTime.Now,
            HistoryAction = ScrawlConstants.HistoryActions.Update,
            ModifiedbyUser = user
        };
        doc.HistoryRecords.Add(history);
        _context.SaveChanges();

发生SaveChanges时,会发生以下异常:

System.Data.SqlServerCe.SqlCeException: A duplicate value cannot be inserted into a unique index. [ Table name = DocumentHistories,Constraint name = PK__DocumentHistories__000000000000006E ]

理论上,由于日期时间不同,每条记录都应该是唯一的,但事实并非如此。我做错了什么?

1 个答案:

答案 0 :(得分:2)

大多数机器上的时钟精度不足以在每次读取时产生不同的值。

相反,在典型系统上,精度约为10-15ms。这意味着在同一“窗口”内连续读取时钟将产生完全相同的值。

有关此主题的一些信息,请参阅DateTime.Now文档。不同的文档来源给出了不同的数字,但相关的信息是它不够准确。一个来源规定了1/64秒,相当于15.625ms。

您应该切换到保证唯一的内容,例如Guid(尽管您丢失了数据的排序属性)或使用服务器生成的身份密钥。