czuroski
czuroski

Reputation: 4332

problem with linq to nhibernate and eager loading in mvc application

Hello I have the following code to retrieve data from my db using nhibernate 3.0 with linq -

public IQueryable<myEntity> getEntityWithChild
        {
            get { return _currentSession.Query<myEntity>().Fetch(c => c.myOtherEntity); }
        }

When I try to pass that to a view, I am getting the following error which isn't very specific. This worked fine when I wasn't eager loading using the following -

public IQueryable<myEntity> getEntityWithChild
            {
                get { return _currentSession.Query<myEntity>(); }
            }

But I was creating a seperate query each time the other entity would be lazy loaded. Has anyone seen this before that may be able to point me in the right direction. Thanks for any thoughts.

System.NotSupportedException was unhandled by user code
  Message=Specified method is not supported.
  Source=NHibernate
  StackTrace:
       at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource)
       at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree)
       at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()
       at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process(IASTNode ast, ISessionFactoryImplementor factory)
       at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
       at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
       at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
       at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
       at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
       at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
       at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression)
       at Remotion.Data.Linq.QueryableBase`1.GetEnumerator()
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
       at vCalWebCalendar.Controllers.HomeController.Hearings() in C:\Users\carl.PAMB.000\Documents\Visual Studio 2010\Projects\Calendar\Calendar\Controllers\HomeController.cs:line 41
       at lambda_method(Closure , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: 

Upvotes: 2

Views: 2748

Answers (3)

hcoverlambda
hcoverlambda

Reputation: 1330

Evidently this is fixed in NH 3.1: https://nhibernate.jira.com/browse/NH-2502

Upvotes: 0

James Kovacs
James Kovacs

Reputation: 11651

Looks like a bug or limitation of the current LINQ provider. The Fetch() clause needs to be the very last method in the chain - even after Select(). So this produces the above exception:

_currentSession.Query<myEntity>().Fetch(c => c.myOtherEntity).Select(x => x);

whereas this works:

_currentSession.Query<myEntity>().Select(x => x).Fetch(c => c.myOtherEntity);

Since you're returning an IQueryable, I suspect that you're filtering or selecting higher up in your application stack, which would cause the .Fetch() to throw an exception. Mike Hadlow has more information about this annoyance on his blog here:

http://mikehadlow.blogspot.com/2010/08/nhibernate-linq-eager-fetching.html

Upvotes: 4

Chris Shouts
Chris Shouts

Reputation: 5427

According to Mike Hadlow's blog post NHibernate Linq Eager Fetching,

Note that if you want to mix Fetch with other clauses, Fetch must always come last.

Is the query in your question the exact query that you are executing?

Upvotes: 5

Related Questions