NHibernate の次の単純なクラスを考えてみましょう。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MyTests.Tests"
namespace="MyTests.Tests">
<class name="TestClass" table="TestTable" dynamic-update="true">
<id name="Id" column="Id" type="UInt64" unsaved-value="0">
<generator class="native" />
</id>
<property name="Date1" type="UtcDateTime"></property>
</class>
</hibernate-mapping>
クラスは次のように定義されます。
public class TestClass {
virtual public UInt64 Id { get; set; }
virtual public DateTime? Date1 { get; set; }
}
次のユースケースは、MySql と SQLite に対して実行すると、異なる結果を生成します。
[Test]
public void Test1() {
//Get Now without Milliseconds
DateTime now = DateTime.UtcNow;
now = new DateTime(now.Ticks - (now.Ticks % TimeSpan.TicksPerSecond), now.Kind);
TestClass tc1 = new TestClass() { Date1 = now };
using(ISession s = NewSession(c))
using(ITransaction tx = s.BeginTransaction()) {
s.Save(tc1);
tx.Commit();
}
using(ISession s = NewSession(c))
using(ITransaction tx = s.BeginTransaction()) {
TestClass tc2 = s.Load<TestClass>(tc1.Id);
Assert.IsNotNull(tc2);
Assert.AreEqual(DateTimeKind.Utc, tc1.Date1.Value.Kind, "Checking kinds of tc1");
Assert.AreEqual(tc1.Date1.Value.Kind, tc2.Date1.Value.Kind, "Comparing Kinds");
Assert.AreEqual(now, tc2.Date1, "Comparing datetime values");
}
}
使用されているデータベースが SQLite の場合、最後のアサートは失敗します。
SQLite ファイルの内部を見ると、日付が正しい (UTC 値) であることがわかります。
読み戻すと DateTimeKind.Utc で読み取られますが、値は現地時間です。
MySql を使用すると、この問題は発生しません。
SQLite のテーブルは、NHibernate によって CreateSchema で作成され、SQLite Administrator によって次のように報告されます。
CREATE TABLE TestTable (Id integer primary key autoincrement, Date1 DATETIME)
親愛なる達人、あなたは問題と解決策が何であるか知っていますか? 誰かが以前に見たに違いない問題のようです...
ありがとうティメック