Equals implementation of NHibernate Entities, a question about getting underlying type from proxies.

120 views
Skip to first unread message

Can Gencer

unread,
Apr 16, 2011, 10:46:40 AM4/16/11
to nhusers
In NHibernate 3.0 Cookbook, there is a sample implementation for a
base Entity type. The equals is implemented like this:

public abstract class Entity<TId>
{
public virtual TId Id { get; protected set; }

public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}

private static bool IsTransient(Entity<TId> obj)
{
return obj != null && Equals(obj.Id, default(TId));
}

private Type GetUnproxiedType()
{
return GetType();
}

public virtual bool Equals(Entity<TId> other)
{
if (other == null) return false;
if (ReferenceEquals(this, other)) return true;

if (!IsTransient(this) && !IsTransient(this) && Equals(Id,
other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
}

The reason for the GetUnproxiedType() method is this: There is an
abstract base class Product, a concrete class Book which inherits from
Product and a dynamic proxy class ProductProxy used by NHibernate for
lazy loading. If a ProductProxy representing a Book and a concrete
Book have the same Ids, they should be treated as equal. However I
don't really see why calling GetType() on a ProductProxy instance
should return Product in this case, and how it helps. Any ideas?

cremor

unread,
Apr 18, 2011, 4:28:04 AM4/18/11
to nhusers
Proxies of entities that are mapped with inheritance are always just
proxies of the base class because NHibernate can't know which subclass
it is when it creates the proxy.

I don't know how GetUnproxiedType() exactly works but I know that it
only works if you are using Castle as proxy factory. So in case you
use any other proxy factory (or update to NHibernate 3.2 and use the
default proxy factory there), you should use a different method to get
the real type.

I'm using the following method:

public static Type GetUnproxiedType(Type type) {
while (type.Assembly.IsDynamic && type.BaseType != null) {
type = type.BaseType;
}

return type;

2qip2...@mail.ru

unread,
Jun 10, 2011, 10:36:01 AM6/10/11
to nhusers
We use LinFu proxy factory. Alas, private Type GetUnproxiedType() did
not work too. It just returned proxy type when variable "other" was
proxy:
var otherType = other.GetUnproxiedType();
But!
I changed it to
public virtual Type GetUnproxiedType()
and it started to unproxy!

2qip2...@mail.ru

unread,
Jun 10, 2011, 10:37:34 AM6/10/11
to nhusers
At LinFu proxy factory, I just changed "private" at GetUnproxiedTypу
to "public virtual" and voila! It started to unproxy :)
Reply all
Reply to author
Forward
0 new messages