views:

150

answers:

2

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), 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.

+1  A: 

I believe you need to override GetHashCode and Equals in your entities.

James Gregory
That's what Compare .NET Objects is supposed to do, so I don't have to override those in every POCO and then update them whenever the POCOs change.
Daniel T.
I marked your answer as the correct one because I really like Fluent NHibernate :). Keep up the good work!
Daniel T.
+1  A: 

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.).

Martin R-L
Right you are. I got around the problem by downloading the source for Compare .NET Objects and disabling the GetType() equality check. This means that you have to pass in the same types or else it'll throw an exception at some point, but I'm willing to live with that considering I'm only using it to compare POCOs.
Daniel T.