Как остановить шкалу DateTimeOffset, чтобы вызвать исключение ChangeConflictException в linq to Sql? - PullRequest
2 голосов
/ 04 февраля 2009

Следующий код пытается создать новую запись и затем изменить ее после того, как она была зафиксирована в базе данных. Последний вызов SubmitChanges () вызывает исключение ChangeConflictException.

ItemA itemA = new ItemA();
itemA.Foo = "a";
itemA.Created = DateTimeOffset.Now.UtcDateTime;

ItemAs.InsertOnSubmit(itemA);
SubmitChanges();

itemA.Foo = "b";
SubmitChanges();

Изучив dataContext.ChangeConflicts, я обнаружил, что столбец «Создан» находился в конфликте, даже несмотря на то, что указанные значения CurrentValue и DatabaseValue выглядели идентичными. При ближайшем рассмотрении я обнаружил, что клещи немного отличаются. Поскольку я установил для столбца DateTimeOffset в базе данных масштаб 3, т. Е. До миллисекунды, это не то же самое, что версия значения .NET, которая, как я считаю, имеет масштаб 7. В результате Linq to Sql замечает несоответствие и считает, что между вставкой и обновлением, показанными выше, что-то изменило базу данных.

Помимо написания метода расширения или чего-то, что я могу использовать для изменения точности в .NET, есть ли лучший способ справиться с этим?


Обновление

Мне пришлось положиться на метод расширения, который должен вызываться при установке столбцов DateTimeOffset в модели.

public static DateTimeOffset ToUniversalTime(this DateTimeOffset dto, int scale) {
    DateTimeOffset utc = dto.ToUniversalTime();
    return utc.AddTicks(-(utc.Ticks % (int)Math.Pow(10, 7 - scale)));
}

Который затем можно назвать:

EntityFoo.Created = DateTimeOffset.Now.ToUniversalTime(3)

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

1 Ответ

1 голос
/ 10 марта 2009

Поскольку вы всегда используете Universal Time, я не могу понять, какое преимущество DateTimeOffset дает вам по сравнению с DateTime. Вы можете использовать DateTime.UtcNow, который имеет ту же точность, что и DateTime Sql Server.

В качестве альтернативы, поскольку вы используете Sql Server 2008, вы можете сохранить свое поле как DateTime2 в базе данных: это имеет дополнительную точность, которую вам требуется.

...