Reputation: 25628
I have the following classes:
public abstract class FooBase
{
public virtual Guid Id { get; set; }
}
public class FooTypeA : FooBase
{
public virtual string TypeAStuff { get; set; }
}
public class Bar
{
public virtual Guid Id { get; set; }
public virtual FooBase Foo { get; }
}
FooBase and FooTypeA are mapped using the table-per-class-heirarchy pattern. Bar is mapped like this:
public class BarDbMap : ClassMap<Bar>
{
public BarDbMap()
{
Id(x => x.Id);
References(x => x.Foo)
.LazyLoad();
}
}
So when I load a Bar, its Foo property is only a proxy.
How do I get the subclass type of Foo (i.e. FooTypeA)?
I have read through a lot of NH docs and forum posts. They describe ways of getting that work for getting the parent type, but not the subclass.
If I try to unproxy the class, I receive errors like: object was an uninitialized proxy for FooBase
Upvotes: 6
Views: 2743
Reputation: 25628
I worked out how to avoid the exception I was receiving. Here is a method that unproxies FooBase:
public static T Unproxy<T>(this T obj, ISession session)
{
if (!NHibernateUtil.IsInitialized(obj))
{
NHibernateUtil.Initialize(obj);
}
if (obj is INHibernateProxy)
{
return (T) session.GetSessionImplementation().PersistenceContext.Unproxy(obj);
}
return obj;
}
Upvotes: 10
Reputation: 49261
Add a Self property to FooBase and use that to check the type:
public abstract class FooBase
{
public virtual Guid Id { get; set; }
public virtual FooBase Self { return this; }
}
Usage:
if (Bar.Foo.Self is FooTypeA) { // do something }
Upvotes: 2
Reputation: 1063
To get the "unproxied" type you could add a method like this to FooBase:
public virtual Type GetTypeUnproxied() {
return GetType();
}
When this method is invoked on a proxy the type of the underlying object will be returned.
However, from your description it seems you are trying to do this outside of the NHibernate session and that won't work with this strategy either. To invoke any method on the proxy where the call is proxied to the underlying object it needs to be instantiated and that can only happen within the NHibernate session since the actual type of the object is stored in the database (in a discriminator column for the table-per-class-hierarchy inheritance strategy). So my guess is that you need to make sure that the proxy is initialized before closing the session if you need to check the type later.
If the reason for lazy loading the Bar->FooBase relation is that FooBase (or a derived type) might contain large amounts of data and you are using NHibernate 3 you could use lazy properties instead.
Upvotes: 1