如何将对象与NHibernate代理对象进行比较?

时间:2009-11-18 23:29:21

标签: nhibernate fluent-nhibernate proxy comparison lazy-loading

我正在使用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();

但这对我来说是最后一个选择,因为它消除了延迟加载的好处。

2 个答案:

答案 0 :(得分:4)

我认为您需要覆盖实体中的GetHashCodeEquals

答案 1 :(得分:1)

比较.NET Objects正在做正确的事情,因为实例不同(类型不同,它就像你自己说的那样是代理)。

我们在几年前使用NHibernate的项目上所做的就是为我们的实体“层超类型”实现我们自己的GetUnderlyingType()(从Enum类中窃取的名称)。

GetUnderlyingType()只是返回基类'type,如果它是代理。

然后在我们的Equals()方法中使用该方法而不是GetType()(在教科书中使用,由R#等)。