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

问题描述:

我使用Compare .NET Objects来测试我的POCO是否正确地保存到测试数据库。让我们举个例子POCO:如何将对象与NHibernate代理对象进行比较?

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()。我的问题是,如何让NHibernate在我尝试使用Compare .NET对象时透明地返回对象而不是代理?或者比较.NET对象与NHib不兼容?

附加信息:

我使用比较.NET对象,所以我不必写每个属性相等测试。我的POCO可能不得不改变,如果我有一个可以使用反射进行深入比较的工具,它将会有很大的帮助。

另外,我知道我可以在我的映射类使用此让物业不懒负载:

References(x => x.Noah).Not.LazyLoad().Cascade.All(); 

但是,这将是我最后的选择,因为它消除了延迟加载的好处。

我相信你需要在你的实体中覆盖GetHashCodeEquals

+0

这就是比较.NET对象应该做的事情,所以我不必在每个POCO中覆盖这些对象,然后在POCO更改时更新它们。 – 2009-11-19 21:36:14

+0

我标记你的答案是正确的,因为我真的很喜欢流利NHibernate :)。保持良好的工作! – 2009-11-21 00:29:03

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

几年前,我们在一个使用NHibernate的项目上做了什么,实现了我们自己的GetUnderlyingType()(名字从Enum类中被盗)为我们的实体“层超类型”。

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

然后,在我们的Equals()方法中使用该方法,而不是GetType()(如在R#中使用的文本书中所示)。

+1

你是对的。我通过下载Compare .NET Objects的源代码并禁用GetType()相等性检查来解决这个问题。这意味着你必须传入相同的类型,否则它会在某个时候抛出异常,但我愿意接受这一点,因为我只是用它来比较POCO。 – 2009-11-21 00:31:23

+0

这是一个实现:http://*.com/questions/2664245/identifying-nhibernate-proxy-classes/2666395#2666395 – 2011-11-13 16:33:49