我试图使用NHibernate来持久化实体,但我的DateTime?
属性在1753年之前的日期没有被保留。我知道这是DATETIME
这个事实下限,但在这种情况下,我的属性由DATE
列支持,根据the docs,该列能够处理0001-01-01
到9999-12-31
的日期
如果我试图坚持1752年1月1日,NHibernate会为NULL
列插入DateOfBirth
。
这发生在一个更大的项目中,但我花时间创建了一个这样的小型复制品:
将以下hbm文件添加为嵌入式资源:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateTests" namespace="NHibernateTests">
<class name="Person">
<id name="Id">
<generator class="native" />
</id>
<property name="Name" />
<property name="DateOfBirth" type="Date" />
</class>
</hibernate-mapping>
将以下代码添加到.cs文件中:
using System;
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
namespace NHibernateTests
{
public class Person
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual DateTime? DateOfBirth { get; set; }
}
[TestFixture]
public class Tests
{
private ISessionFactory factory;
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
var configuration = new Configuration();
configuration.DataBaseIntegration(db =>
{
db.ConnectionString = @"data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=NhTestDb";
db.Dialect<MsSql2012Dialect>();
});
configuration.AddAssembly(Assembly.GetExecutingAssembly());
configuration.CurrentSessionContext<NHibernate.Context.ThreadStaticSessionContext>();
factory = configuration.BuildSessionFactory();
using (var schemaCreationSession = factory.OpenSession())
{
new SchemaExport(configuration).Execute(true, true, false, schemaCreationSession.Connection, Console.Out);
}
}
[Test]
public void Can_Persist_DateOfBirth()
{
var session = factory.OpenSession();
var person = new Person {Name = "John", DateOfBirth = new DateTime(1752, 1, 1)};
session.Save(person);
session.Refresh(person);
session.Dispose();
Assert.That(person.Name, Is.EqualTo("John"));
Assert.That(person.DateOfBirth, Is.EqualTo(new DateTime(1752, 1, 1)));
}
}
}
并且看到测试失败,因为DateOfBirth实际上是null
。
我已经使用调试器进行了双重检查,DateOfBirth
实际上在保存之前就已设置为正确的值。
我已经仔细检查过生成的列实际上是Date
,并检查the docs此类型的范围是否足够大;
我还检查了其他属性 是否被保留:请参阅NUnit测试,该测试断言Name
属性的持久性。
我已经通过NuGet添加了log4net并配置了NHibernate来输出格式化的SQL,如下所示:
INSERT INTO Person (Name, DateOfBirth)
VALUES (@p0, @p1);
select SCOPE_IDENTITY();
-- @p0 = 'John' [Type: String (4000)],
-- @p1 = NULL [Type: DateTime (0)]
所以实际上 NHibernate 似乎给我带来了麻烦:它明确地插入了NULL
。我通过使用SSMS手动插入一行来进行双重检查,SSMS接受'16000101'
作为值。
最后,我使用new DateTime(1900, 1, 1)
重新运行测试,该测试保持不变。
结论:我如何让NHibernate在1753年之前坚持下去?
答案 0 :(得分:0)
我的问题与this one非常相似,我估计只是重复一次。在任何情况下,the answer there by @JimFennel也是我的解决方案。将我的属性映射更改为此...
<property name="DateOfBirth" type="DateTime2">
<column name="DateOfBirth" sql-type="date" />
</property>
...也解决了我的特殊问题。