Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate 3 LINQ inner join issue with three jumps: NotSupportedException

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

like image 618
kaptan Avatar asked Jan 04 '11 22:01

kaptan


1 Answers

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.

like image 86
mpontillo Avatar answered Nov 02 '22 14:11

mpontillo