2009-11-18 95 views
1

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

但是,這將是我最後的選擇,因爲它消除了延遲加載的好處。

回答

4

我相信你需要在你的實體中覆蓋GetHashCodeEquals

+0

這就是比較.NET對象應該做的事情,所以我不必在每個POCO中覆蓋這些對象,然後在POCO更改時更新它們。 – 2009-11-19 21:36:14

+0

我標記你的答案是正確的,因爲我真的很喜歡流利NHibernate :)。保持良好的工作! – 2009-11-21 00:29:03

1

比較.NET Objects正在做正確的事情,因爲實例不同(類型不同,它是一個代理,就像你自己說的那樣)。

幾年前,我們在一個使用NHibernate的項目上做了什麼,實現了我們自己的GetUnderlyingType()(名字從Enum類中被盜)爲我們的實體「層超類型」。

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

然後,在我們的Equals()方法中使用該方法,而不是GetType()(如在R#中使用的文本書中所示)。

+1

你是對的。我通過下載Compare .NET Objects的源代碼並禁用GetType()相等性檢查來解決這個問題。這意味着你必須傳入相同的類型,否則它會在某個時候拋出異常,但我願意接受這一點,因爲我只是用它來比較POCO。 – 2009-11-21 00:31:23

+0

這是一個實現:http://stackoverflow.com/questions/2664245/identifying-nhibernate-proxy-classes/2666395#2666395 – 2011-11-13 16:33:49