开发者

Verifying datetime fluent nhibernate mappings

I'm encountering an issue when verifying the mappings on a very simple class.

System.ApplicationException : For property 'Created' expected same element, but got different element with the same value '8/9/2011 12:07:55 AM' of type 'System.DateTime'. Tip: use a CustomEqualityComparer when creating the PersistenceSpecification object.

I have tried creating overrides for the equals and get hashcode methods and that resulted in the same error. I dug into the custom equality comparer for per开发者_如何学JAVAsistence specification testing and again hit the same error. I should perhaps take a look at this with a fresh set of eyes in the morning but I feel i'm missing something very basic.

Thanks all.

public class Blah
{
    public int Id { get;  set; }
    public DateTime Created { get; set; }
    public string Description { get; set; }
}

[Test]
public void Can_Correctly_Map_Blah()
{
    new PersistenceSpecification<Blah>(Session)
        .CheckProperty(c => c.Id, 1)
        .CheckProperty(c => c.Description, "Big Description")
        .CheckProperty(c => c.Created, System.DateTime.Now)
        .VerifyTheMappings();
}


You have to be careful when comparing date times because it may seem like they are the same but they can vary down to the ticks (100 nanoseconds). It's probably failing because sql server doesn't store the date times that accurately.

You'll need use a custom equality comparer such that you only compare year, month, day, hour, minute and second probably.

Take a look at this article too: Why datetime cannot compare?


I just ran into this while using an in-memory SQLite session. I debugged through it and noticed that the DateTimes' "Milliseconds" and "Kind" properties differed ("Utc" Kind vs. "Unspecified").

My implementation per Cole W's suggestion:

class DateTimeEqualityComparer : IEqualityComparer
{
    private TimeSpan maxDifference;

    public DateTimeEqualityComparer(TimeSpan maxDifference)
    {
        this.maxDifference = maxDifference;
    }

    public bool Equals(object x, object y)
    {
        if (x == null || y == null)
        {
            return false;
        }
        else if (x is DateTime && y is DateTime)
        {
            var dt1 = (DateTime)x;
            var dt2 = (DateTime)y;
            var duration = (dt1 - dt2).Duration();
            return duration < maxDifference;
        }
        return x.Equals(y);
    }

    public int GetHashCode(object obj)
    {
        throw new NotImplementedException();
    }
}

Your specification test becomes something like this:

var maxDifference = TimeSpan.FromSeconds(1);
...
new PersistenceSpecification<Blah>(Session)
    ...
    .CheckProperty(c => c.Created, System.DateTime.Now,
            new DateTimeEqualityComparer(maxDifference))


Simple solution is to create a new instance of the DateTime

[Test]
public void Can_Correctly_Map_Blah()
{
    new PersistenceSpecification<Blah>(Session)
        .CheckProperty(c => c.Id, 1)
        .CheckProperty(c => c.Description, "Big Description")
        .CheckProperty(c => c.Created,  new DateTime(2016, 7, 15, 3, 15, 0) )
        .VerifyTheMappings();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜