我正在使用Compare .NET Objects来测试我的POCO是否正确地保存到测试数据库中。我们举个例子POCO:
public class NoahsArk
{
public virtual Noah Noah { get; set; }
}
映射文件,使用FNH:
public class NoahsArkMap : ClassMap<NoahsArk>
{
References(x => x.Noah).Cascade.All();
}
现在,我运行此代码:
var noahsArk = new NoahsArk { new Noah() }; // create a new ark
var dbNoahsArk = database.SaveAndLoad(noahsArk); // saves the ark to the db and loads it again into another object
Assert.That(new CompareObjects().Compare(noahsArk, dbNoahsArk), Is.True); // will return true if all properties (including collections) are equal
Assert()
失败,因为它将noahsArk.Noah
视为Noah
对象,但dbNoahsArk.Noah
视为NHibernate代理对象。我不知道NHibernate在后台做了什么,因为如果我这样做:
Assert.That(noahsArk.Noah, Is.EqualTo(dbNoahsArk.Noah));
它工作正常,即使两个对象的类型都不同,如果我在两者上都GetType()
。我的问题是,当我尝试使用Compare .NET Objects时,我怎样才能使NHibernate“透明地”返回对象而不是代理?或者是比较与NHib不兼容的.NET对象?
其他信息:
我正在使用Compare .NET Objects,因此我不必为每个属性编写相等测试。我的POCO可能不得不改变,如果我有一个可以使用Reflection进行深度比较的工具,它将会有很大的帮助。
另外,我知道我可以通过在我的映射类中使用它来使属性不是延迟加载:
References(x => x.Noah).Not.LazyLoad().Cascade.All();
但这对我来说是最后一个选择,因为它消除了延迟加载的好处。
答案 0 :(得分:4)
我认为您需要覆盖实体中的GetHashCode
和Equals
。
答案 1 :(得分:1)
比较.NET Objects正在做正确的事情,因为实例不同(类型不同,它就像你自己说的那样是代理)。
我们在几年前使用NHibernate的项目上所做的就是为我们的实体“层超类型”实现我们自己的GetUnderlyingType()(从Enum类中窃取的名称)。
GetUnderlyingType()只是返回基类'type,如果它是代理。
然后在我们的Equals()方法中使用该方法而不是GetType()(在教科书中使用,由R#等)。