NHibernate 3 LINQ inner join issue with three jumps: NotSupportedException
Asked Answered
T

2

6

I have a query that used to work in NHibernate LINQ 2.1.2 but it is throwing NotSupportedException with NH3:

    IQueryable<Tree> query = from flower in GetSession().Query<Flower>()
                             from leaf in flower.Stem.Leaves // <--- the problem is here with three jumps
                             where leaf.Color == Green
                             select flower;

The relations are like:

  • Flower References Stem
  • Stem HasMany Flowers
  • Leaf References Stem
  • Stem HasMany Leaves

The exception is thrown from line 204 in NHibernate.Linq.Visitors.QueryModelVisitor. Here is the method from the source code:

    public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index)
    {
        if (fromClause is LeftJoinClause)
        {
            // It's a left join
            _hqlTree.AddFromClause(_hqlTree.TreeBuilder.LeftJoin(
                                 HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(),
                                 _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));
        }
        else if (fromClause.FromExpression is MemberExpression)
        {
            var member = (MemberExpression) fromClause.FromExpression;

            if (member.Expression is QuerySourceReferenceExpression)
            {
                // It's a join
                _hqlTree.AddFromClause(_hqlTree.TreeBuilder.Join(
                                     HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(),
                                     _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));
            }
            else
            {
                // What's this?
                throw new NotSupportedException(); // <--------- LINE 204
            }
        }
        else
        {
            // TODO - exact same code as in MainFromClause; refactor this out
            _hqlTree.AddFromClause(_hqlTree.TreeBuilder.Range(
                                 HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters),
                                 _hqlTree.TreeBuilder.Alias(fromClause.ItemName)));

        }

        base.VisitAdditionalFromClause(fromClause, queryModel, index);
    }

It seems to me the same issue is discussed under the following thread:

http://groups.google.com/group/nhusers/browse_thread/thread/dbceb7eb1e31f027/f8e69671b750e0d6?lnk=gst&q=NotSupportedException+stefan#f8e69671b750e0d6

Under that thread Stefan mentions that the syntax is not supported:

The LINQ provider expects the expression to be:

QuerySourceReferenceExpression . Member

However, in the case of from brw in loan.Application.Borrowers it is:

QuerySourceReferenceExpression . Member . Member

So it's definately an unsupported feature.

So, is this syntax going to be supported anytime in NH3 LINQ? I think it is a trivial syntax and it's good to have.

However I can go around this issue by rewriting the query as:

        IQueryable<Tree> query = from stem in  GetSession().Query<Stem>()
                                 from leaf in stem.Leaves
                                 from flower in stem.Flowers
                                 where leaf.Color == Green
                                 select flower;

BTW, anyone has a better workaround?

nhusers link: http://groups.google.com/group/nhusers/browse_thread/thread/334a53c749b0b377

Truong answered 4/1, 2011 at 22:20 Comment(0)
M
1

After all that effort put in, your question:

is this syntax going to be supported anytime in NH3 LINQ?

... simply cannot be answered in this forum. NHibernate is not a commercial product with a roadmap. You can't just post here and hope one of the volunteer developers responds.

Remember that NHibernate is open source, so the community (including you!) owns issues like this.

I have been following the the nhibernate-development list, and it looks like the LINQ provider is a major area of work. However, I don't know if your specific issue will be addressed. The best way to increase the chances of this issue being fixed is to file a bug in the NHibernate JIRA along with a test case showing the problem.

If it doesn't look like your specific issue will be addressed, why not download the source code and try fixing it yourself, and/or discussing it further on the mailing list? If you download the source code and work with it a little, you'll also find that it has plenty of great example test cases that you can use as examples when you file the bug.

Millinery answered 5/2, 2011 at 4:23 Comment(4)
Care to explain the -1? I offered useful suggestions about how the issue might end up getting visibility and/or eventually resolved. Just because it's the answer you don't want to hear doesn't mean it should be voted down. ;-)Millinery
you get my vote. A lot of .Net people think of OSS the same as commercial apps, and don't ever think about how they can contribute themselves. (Although, that said, even as an experienced developer, the NH codebase is intimidating)Plenitude
Just found this article which could be helpful when going down this path.Millinery
I don't know about the -1 but I gave you a +1. Your explanation makes sense and I think it will be useful for other readers too. I can't just mark it as answer because what I was really looking for is a kind of better workaround for this issue. I should have structured my question in a better way to be more clear.Truong
C
1

Haven't tested your exact example but I had a similar issue in NH 3.2 and found that is has been resolved in NH 3.3

Cunnilingus answered 29/5, 2012 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.