Почему я получаю нарушения первичных ключей при вставке этих записей?(EF4 Code-First) - PullRequest
2 голосов
/ 20 февраля 2011

У меня есть следующая сущность

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 Ответ

2 голосов
/ 21 февраля 2011

Точность часов на большинстве машин недостаточно высока, чтобы каждый раз при чтении их показывать разные значения.

Вместо этого в типичной системе точность составляет около 10-15 мс.Это означает, что последовательные чтения часов в одном и том же «окне» будут давать одно и то же значение.

См. Документацию DateTime.Now для получения дополнительной информации по этому вопросу.Разные источники документации дают разные цифры, но соответствующая информация заключается в том, что она недостаточно точна.Один источник указывал 1/64 секунды, что означает 15,625 мс.

Вместо этого вам следует переключиться на что-то, что гарантированно будет уникальным, например Guid (хотя вы потеряете свойство упорядочения данных).или используйте сгенерированный сервером идентификационный ключ.

...