Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent NHibernate CheckProperty and Dates

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.

like image 243
Chris C Avatar asked Feb 23 '10 18:02

Chris C


1 Answers

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());
like image 88
GreenMoose Avatar answered Oct 24 '22 04:10

GreenMoose