I'm using Compare .NET Objects to test whether my POCOs are persisted correctly to a test database. Let's take an example POCO:
public class NoahsArk
{
public virtual Noah Noah { get; set; }
}
And the mapping file, using FNH:
public class NoahsArkMap : ClassMap<NoahsArk>
{
References(x => x.Noah).Cascade.All();
}
Now, I run this code:
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)开发者_StackOverflow中文版, Is.True); // will return true if all properties (including collections) are equal
The Assert()
fails because it sees noahsArk.Noah
as a Noah
object, but the dbNoahsArk.Noah
as a NHibernate proxy object. I don't know what NHibernate is doing in the background because if I do this instead:
Assert.That(noahsArk.Noah, Is.EqualTo(dbNoahsArk.Noah));
It works fine, even though both objects' types are different if I do GetType()
on both. My question is, how can I make it so that NHibernate will 'transparently' return the object instead of the proxy when I try to use Compare .NET Objects with it? Or is Compare .NET Objects not compatible with NHib?
Additional Information:
I'm using Compare .NET Objects so I don't have to write equality tests for every property. My POCOs will likely have to change and it will help greatly if I had a tool that can do deep comparisons using Reflection.
Also, I know I can make the property not lazy load by using this in my mapping class:
References(x => x.Noah).Not.LazyLoad().Cascade.All();
But that would be a last option for me because it removes the benefit of lazy loading.
I believe you need to override GetHashCode
and Equals
in your entities.
Compare .NET Objects is doing the right thing since the instances differ (the types are different, it's a proxy just as you say yourself).
What we had to to on a project that used NHibernate some years ago, was implementing our own GetUnderlyingType() (name stolen from the Enum class) for our entity "layer super type".
GetUnderlyingType() simply returns the base class' type if it's a proxy.
That method was then used in our Equals() method instead of GetType() (as used in the text book, by R#, etc.).
精彩评论