在验证非常简单的类上的映射时遇到问题。
System.ApplicationException:对于属性“ Created”,预期相同元素,但具有相同值'8/9/2011的其他元素类型为“ System.DateTime”的“ 12:07:55 AM”。提示:使用创建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();
}
比较日期时间时请务必小心,因为看起来好像它们是相同的,但是它们可以变化到刻度(100纳秒)。这可能是失败的,因为sql server不能准确地存储日期时间。
您将需要使用自定义的相等比较器,以便仅可能比较年,月,日,时,分和秒。
也看一下这篇文章:Why datetime cannot compare?
我只是在使用内存中SQLite会话时遇到了这个问题。我调试了一下,发现DateTimes的“毫秒”和“种类”属性有所不同(“ Utc”种类与“未指定”)。
我根据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))
简单的解决方案是创建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();
}