Fluent NHibernate CheckProperty 和日期

发布于 2024-08-22 14:53:56 字数 577 浏览 8 评论 0原文

我这样设置 NUnit 测试:

new PersistenceSpecification<MyTable>(_session)
    .CheckProperty(c => c.ActionDate, DateTime.Now);

当我通过 NUnit 运行测试时,出现以下错误:

SomeNamespace.MapTest: 
System.ApplicationException : Expected '2/23/2010 11:08:38 AM' but got 
'2/23/2010 11:08:38 AM' for Property 'ActionDate'

ActionDate 字段是 SQL 2008 数据库中的日期时间字段。我使用自动映射并将 ActionDate 声明为 C# 中的 DateTime 属性。

如果我将测试更改为使用 DateTime.Today 测试就会通过。

我的问题是为什么 DateTime.Now 测试失败?将日期保存到数据库时,NHibernate 是否会丢失一些精度?如果是,如何防止丢失?谢谢。

I setup a NUnit test as such:

new PersistenceSpecification<MyTable>(_session)
    .CheckProperty(c => c.ActionDate, DateTime.Now);

When I run the test via NUnit I get the following error:

SomeNamespace.MapTest: 
System.ApplicationException : Expected '2/23/2010 11:08:38 AM' but got 
'2/23/2010 11:08:38 AM' for Property 'ActionDate'

The ActionDate field is a datetime field in a SQL 2008 database. I use Auto Mapping and declare the ActionDate as a DateTime property in C#.

If I change the test to use DateTime.Today the tests pass.

My question is why is the test failing with DateTime.Now? Is NHibernate losing some precision when saving the date to the database and if so how do prevent the lose? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

扬花落满肩 2024-08-29 14:53:56

由于 sql server 无法存储所有毫秒(但四舍五入为 .003/.004/.007 秒的增量,如您在 msdn),您应该在将 C# 中的 DateTime 值传递给 CheckProperty 方法之前将其截断,因为从数据库检索到的 DateTime 与您的 DateTime.Now 不同导致精度损失。

例如,如果您只需要秒的精度,则可以截断毫秒,如 SO 问题的答案所示: 如何截断 .NET DateTime 的毫秒

如果您需要更高的精度,则应使用 timestamp 映射类型。

您可以使用扩展方法轻松截断毫秒:

public static class DateTimeExtension
{
  public static DateTime TruncateToSeconds(this DateTime source)
  {
    return new DateTime(source.Ticks - (source.Ticks%TimeSpan.TicksPerSecond), source.Kind);
  }
}
//<...>
new PersistenceSpecification<MyTable>(_session)
    .CheckProperty(c => c.ActionDate, DateTime.Now.TruncateToSeconds());

Since sql server can't store all milliseconds (but rounded to increments of .003/.004/.007 seconds as you can see at msdn), you should truncate the DateTime value in C# before passing it to the CheckProperty method since the DateTime retrieved from the db isn't identical to your DateTime.Now due to loss of precision.

If you only need precision for seconds for instance, you can truncate the milliseconds as seen in the answer for the SO question: How to truncate milliseconds off of a .NET DateTime.

If you need more precision you should use timestamp mapping type.

You can easily truncate milliseconds by using an extension method:

public static class DateTimeExtension
{
  public static DateTime TruncateToSeconds(this DateTime source)
  {
    return new DateTime(source.Ticks - (source.Ticks%TimeSpan.TicksPerSecond), source.Kind);
  }
}
//<...>
new PersistenceSpecification<MyTable>(_session)
    .CheckProperty(c => c.ActionDate, DateTime.Now.TruncateToSeconds());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文