I've got a table-per-subclass setup using NHibernate & I'm trying to construct a LINQ query which pre-fetches certain properties that can exist in the derived classes, but I just can't work out how to write the query. E.g. Something like:
var elements = session.Query<Element>()
.Fetch(e => e.Design) // Fine, resides in Element
//.Fetch(e => (e as Material)?.Category)
//.Fetch(e => (e as Operational)?.EnergySource)
.Where(e => elementIdList.Contains(e.Id)) // Or similar query
Obviously the above won't work; I need a statement that can actually be converted to SQL -- How can I explicitly instruct NHibernate to fetch a derived class' associations? I.e. Assume in the following classes that Design
, Category
and EnergySource
have <many-to-one>
relationships from their corresponding "Elements"
public class Element
{
public virtual int Id { get; set; }
public virtual Design Design { get; set; }
}
public class Material : Element
{
public virtual Category Category { get; set; }
}
public class Operational : Element
{
public virtual EnergySource EnergySource { get; set; }
}
I can emulate it using ToFuture
queries on both subclasses & then merging the results, or with an appropriate default config + QueryOver<>
, but trying to work out how to do this with Query<>
.
Just use explicit cast to subclass:
var query = session.Query<Element>()
.Fetch(e => ((Material)e).Category)
.Fetch(e => ((Operational)e).EnergySource);
//Same applies to Where clause
.Where( e => ((Material)e).SomeMaterialValue > 10);
Note: NHibernate detects subclasses by property name (actual cast type is not used so the following .Fetch(e => ((UnrelatedClass)e).Category))
will also fetch Material.Category
). It also means that if you have the same property name in different subclasses NHibernate won't be able to properly detect correct subclass.