Hey,
I am starting this thread to discuss all the issues and their solutions regarding using NHibernate with Jet 4.0 databases.
As probably most of you know who ever tried to use NHibernate with Jet that this is doable through the OleDbDriver and setting a bunch of configuration options. Also, there are a few differences between the MsSql7 dialect and Jet's SQL dialect.
Stone Well has already contributed an msaccess2000dialect.cs file and also an msaccess2000joinfragment.cs file
here. The dialect is rather outdated and is missing a bunch of Register* calls that the other dialects in 0.8.4 have. It is perfect as a starting point though.
The huge problem with Jet is its fucked up JOIN syntax. The contributed Join Fragment implementation can only produce inner joins as it implements Jet's alternative SQL syntax (theta-style inner joins). This works for multiple inner joins too. The problem is that left joins and right joins are also treated as inner joins. 'inner join' and 'left join' ends up with the same SQL which is not very smart.
The problem is that there is no alternative syntax for (left and right) outer joins in Jet and all we could do is implement its
nested syntax. The implementation is not trivial because NHibernate treats each join fragment as totally separate part of the full SQL query. In Jet's case, we would want to know all the joins
before we start figuring out the right SQL statement so that we can nest them and open the right amount of parenthesis.
A slightly modified ANSIJoinFragment will work with both inner and outer joins as long as there is only one join in the HQL query (as there is no need for nesting / parenthesis in that case). As soon as there are two or more joins, it won't work, Jet will come back with an error although NHibernate will treat the HQL as correct.
My problem in my project is that I would need two left joins in one query to do something like:
Code:
from Grandparent Grandparent left join fetch Grandparent.Parent Parent left join fetch Parent.Children
Because SQL for both join statements are generated totally separate and there's no
state information, there is no way to figure out how to end up with the correct SQL query which would be:
Code:
SELECT ... FROM Grandparent LEFT JOIN (Parent LEFT JOIN Children ON Children.ParentId=Parent.ParentId) ON Grandparent.GrandparentId=Parent.GrandparentId
I hope I got that right :) Also, there is an alternative way, nesting the JOINs the other way around:
Code:
SELET ... FROM (Grandparent LEFT JOIN Parent ON Grandparent.GrandparentId=Parent.GrandparentId) LEFT JOIN Children ON Parent.ParentId=Children.ParentId
Both syntaxes are just fine but need some kind of a
state-aware SQL generation.
I will post anything I find. Please contribute your ideas or maybe your existing solutions to this problem. It would be nice to bring NHibernate / Jet 4.0 to a point where most of HQL is covered and this feature is a must. A lot of people use Jet databases in production, it's not that bad as people treat it, except the stupid JOIN syntax. I would break the guy's hand who came up with that. :twisted: 8)