Filtering entities by subtype with NHibernate.Linq
-
11-09-2019 - |
Question
Given this inheritance mapping:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="User" table="[User]" abstract="true">
<joined-subclass name="SubUser1" table="SubUser1">
<key column="UserId" />
...
</joined-subclass>
<joined-subclass name="SubUser2" table="SubUser2">
<key column="UserId" />
...
</joined-subclass>
<joined-subclass name="SubUser3" table="SubUser3">
<key column="UserId" />
...
</joined-subclass>
</class>
</hibernate-mapping>
how do I query for all instances of SubUser2
and SubUser3
? I realize I can do this:
session.Linq<User>().OfType<SubUser2>()
but that only allows me to filter by a single type. I tried this:
session.Linq<User>().Where(user => user is SubUser2)
but that resulted in this error:
could not resolve property: of: User
Any ideas on how to express a query against multiple sub-types?
Solution
As far as I can tell, this is not possible. Perhaps it will be in the future. I know they accept patches :-)
I only have about 500 records and 4 types, and am usually querying on 2 or 3 types at the same time. For now, I am applying the filter on each type in the database, then concatenating the result sets and doing ordering and paging in-memory.
It is not the most efficient solution, but works just fine. I chose not to add a superfluous discriminator column to the User table solely to enable this query.
OTHER TIPS
What about something like this:
// Get them in 2 queries
var sub2 = session.Linq<SubUser2>().Select(x => x).ToList();
var sub3 = session.Linq<SubUser3>().Select(x => x).ToList();
// Join together in memory
var sub2And3 = sub2.OfType<User>().Union( sub3.OfType<User>() );