NHibernate Pitfalls: Inheritance and Proxies
This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.
If you use inheritance and lazy loading, you may end up with the following situation:
- You want to access a lazy loaded property of a base class type, of which you don’t know the exact type;
- You want to do different operations depending on the actual type.
That is usually expressed by this mapping:
1: public class MyEntity
2: {
3: public virtual SomeBaseClass SomeProperty
4: {
5: get;
6: set;
7: }
8: }
9:
10: public abstract SomeBaseClass
11: {
12: }
13:
14: public class SomeConcreteClass : SomeBaseClass
15: {
16: }
17:
18: public class AnotherConcreteClass : SomeBaseClass
19: {
20: }
And by this code:
The problem is, SomeProperty may not be neither a SomeConcreteClass nor a AnotherConcreteClass. That is because NHibernate creates a proxy for SomeBaseClass 1: MyEntity e = ...;
2:
3: if (e.SomeProperty is SomeConcreteClass)
4: {
5: }
6: else if (e.SomeProperty is AnotherConcreteClass)
7: {
8: }
The solution is to use the no-proxy option on the mapping:
1: mapper.Class<MyEntity>(c =>
2: {
3: c.ManyToOne(x => x.SomeProperty, x =>
4: {
5: x.Lazy(LazyRelation.NoProxy);
6: });
7: }
This way, NHibernate delays loading of the property, as before, but, instead of returning a proxy to the base class, it will instead return one for the concrete class.
You can find more information on this post by Ayende: http://ayende.com/blog/4378/nhibernate-new-feature-no-proxy-associations.