验证日期时间流畅的nhibernate映射

时间:2011-08-09 06:16:11

标签: c# fluent-nhibernate

我在一个非常简单的类上验证映射时遇到了一个问题。

  

System.ApplicationException:对于'Created'属性,预期相同   元素,但得到了具有相同值的不同元素'8/9/2011   上午12:07:55''System.DateTime'类型。提示:使用   创建PersistenceSpecification时的CustomEqualityComparer   对象

我尝试为equals创建覆盖并获取hashcode方法,这导致了同样的错误。我挖到了持久性规范测试的自定义相等比较器,并再次遇到同样的错误。我或许应该在早上用一双清新的眼睛来看看这个,但我觉得我错过了一些非常基本的东西。

谢谢大家。

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();
}

3 个答案:

答案 0 :(得分:11)

比较日期时间时要小心,因为看起来它们可能相同,但它们可以变化到滴答(100纳秒)。它可能失败了,因为sql server没有准确存储日期时间。

您需要使用自定义相等比较器,这样您才可能只比较年,月,日,小时,分钟和秒。

看看这篇文章: Why datetime cannot compare?

答案 1 :(得分:4)

我在使用内存中的SQLite会话时遇到了这个问题。我通过它调试并注意到DateTimes的“毫秒”和“种类”属性不同(“Utc”Kind vs.“Unspecified”)。

我根据Cole W的建议实施:

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();
    }
}

您的规格测试会变成这样:

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

答案 2 :(得分:0)

简单的解决方案是创建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();
}