次のコードは、新しいレコードを作成し、データベースにコミットされた後に変更しようとします。最後の 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 が同じように見えても、'Created' 列が競合していることがわかりました。よく調べてみると、ティックがわずかに異なっていることがわかりました。データベースの DateTimeOffset 列のスケールを 3、つまりミリ秒に設定したため、スケールが 7 であると思われる .NET のバージョンの値とは異なります。その結果、Linq から 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)
このアプローチはあまり好きではありません。これは、データ コンテキストが行うべきだと思われるスケールを手動で設定する必要があることを意味するからです。