NHibernate: Get a specific type of referenced abstract entity

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 displayed using the table-per-class-heirarchy template. The bar is displayed as follows:

 public class BarDbMap : ClassMap<Bar> { public BarDbMap() { Id(x => x.Id); References(x => x.Foo) .LazyLoad(); } } 

Therefore, when I load Bar, its Foo property is only a proxy.

How to get the subclass type Foo (i.e. FooTypeA)?

I read a lot of NH docs and forum posts. They describe how to get this working to get the parent type, but not a subclass.

If I try the unproxy class, I get errors such as: the object was an uninitialized proxy for FooBase

+4
source share
3 answers

I developed how to avoid the exception that I was getting. Here is the method that frees 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; } 
+8
source

Add the Self property to FooBase and use it to check the type:

 public abstract class FooBase { public virtual Guid Id { get; set; } public virtual FooBase Self { return this; } } 

Using:

 if (Bar.Foo.Self is FooTypeA) { // do something } 
+2
source

To get an โ€œunforgivenโ€ type, you can add a method like this in FooBase:

 public virtual Type GetTypeUnproxied() { return GetType(); } 

When this method is called in the proxy server, the type of the base object is returned.

However, from your description, it seems that you are trying to do this outside of an NHibernate session, and this will not work with this strategy either. To call any method in the proxy server where the call is proxied to the base object, it must be created, and this can only happen in the NHibernate session, since the actual type of the object is stored in the database (in the discriminator column for the table, the inheritance strategy of the hierarchy-class- hierarchy). Therefore, I assume that you need to make sure that the proxy is initialized before the session is closed, if you need to check the type later.

If the reason for lazy loading the Bar-> FooBase relationship is because FooBase (or a derived type) can contain large amounts of data, and you are using NHibernate 3, you can use lazy properties .

+1
source

Source: https://habr.com/ru/post/1342763/


All Articles