When we define a query, sometimes we need to load a graph of related objects as well. This can be impressively helpful with an ORM, but it is also more expensive per query. We have to balance the cost of the query graph with the ease of loading related objects in the code base. The approach to this varies by the underlying ORM that you are using, so please click the link for the section that pertains to you.
In all of the examples below, we’ll be working with the following business domain, from our Driver’s Education company:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Let’s assume that we now need to load Drivers and Cars for the instructor. Because we are only loading one Instructor this should be fairly light weight on the database.
Entity Framework got the API for this correct, so when you unit test this without a database it does nothing with the include call. This allows us to not need an advanced query for the Entity Framework version of the query.
1 2 3 4 5 6 7 8 9
Notice to traverse a collection we have to use the
Select method, this is a quark of LINQ and Entity Framework. As you see below in the NHibernate solution there is a slightly more elegant way they could have done this, but it comes with a hefty cost.
In the NHibernate usage we will have to bind ourselves to their specific API, which means that we will have to use an
1 2 3 4 5 6 7 8 9 10
This reads more fluently but causes us to be bound to NHibernate. It also has one massive bug in NHibernate’s LINQ provider. In the above query you will only get one related driver and one related car. This is because it applies a Top 1 to the queries. To avoid this you must do the below query.
1 2 3 4 5 6 7 8 9 10 11 12
This is a bug in NHibernate