views:

130

answers:

5

Let's say I have a base class called Pet and two subclasses Cat and Dog that inherit Pet.

I simply map these to three tables Pet, Cat and Dog, where the Pet table contains the base class properties and the Cat and Dog tables contain a foreign key to the Pet table and any additional properties specific to a cat or dog. A joined subclass strategy.

Now, using NHibernate and ICriteria, how can I get a list of all the different pets as Pet objects, not Cat or Dog objects - just plain Pet objects, without making any joins to the other tables? I am only interested in the information contained in Pet.

A: 

Hmm, selecting 'as pet' would I think bring back all object (not just the pets that are not subclassed). I don't know of a clean way of doing it, but then I'm not an NH expert.

Maybe you could query the discriminator column in the parent table directly? Although perhaps you would have to resport to a custom SQL query rather than HQL or ICriteria.

UpTheCreek
+1  A: 

I just did something similar and found this blog post by Ayende extremely helpful! I went with a joined-subclass approach and it nicely supports querying the base class.

However, to find "only pets" without joining I think you'd need the table-per-class hierarchy approach. Or, you could use the table-per-subclass and just do left joins on the subclasses and restrict it to rows that had no matches on any of the left joins.

dotjoe
That was a great post by Ayende. I found the unioned subclass strategy to be interesting, I'll have to look into that. I wonder what the performance hit would be if I wanted the top 10 results from like 7 unioned tables though...
Kristoffer
A: 

This seems to work ok:

I created a view that made selected all columns on the Pet table. I then created a simple DTO class that I mapped to the view. After that, ICriteria can be used.

Not the prettiest or cleanest solution perhaps, but certainly easier to work with than dynamic query strings.

Kristoffer
A: 

I don't believe you can do this with the Criteria API. However, you can do it with HQL:

var hql = @"from Pet p where p.class = Pet";
Jamie Ide
This would join all over the place. It would not return cats or dogs as pets, only the ones that are nothing more than pets. Perhaps I was a bit unclear about that I want all pets of all kinds, but only the information that the Pet class contains.
Kristoffer
That's what you asked for: "not Cat or Dog objects - just plain Pet objects" and I wouldn't expect this to produce any joins. If what you really want is Cat or Dog objects "coerced" into Pet objects then you'll have to do it yourself. That's a non-object oriented approach and I wouldn't expect (or want) NH to support it.
Jamie Ide
A: 

Why not create a new map for "PetsOnly" and and remove your discriminator and other non required fields? I think Kristoffer above aluded to the same thing; should still give you full insert update and delete select support. The pet is only a Pet...

AJ