Skip to content

AsQueryable() on collection throws if applied after Where statement #2471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lbcsy opened this issue Aug 8, 2020 · 8 comments
Closed

AsQueryable() on collection throws if applied after Where statement #2471

lbcsy opened this issue Aug 8, 2020 · 8 comments

Comments

@lbcsy
Copy link

lbcsy commented Aug 8, 2020

A query (IQueryable) worked in version 4.0.4 but has exception in 5.2.2:

 'query.ToList()' threw an exception of type 'System.NotSupportedException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2146233067
    HelpLink: null
    InnerException: null
    Message: "query ( query ( select_from ( from ( range ( . _0 RolePrivileges ) a ) ) ( select a ) ) ( where ( and ( == ( . a AccessTypeName ) ( : p12 ) ) ( or ( == ( : p13 ) true ) ( == ( . ( . param002 Role ) Id ) ( : p14 ) ) ) ) ) )"
    Source: "NHibernate"
    StackTrace: "   at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource)\r\n   at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree)\r\n   at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()\r\n   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)\r\n   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)\r\n   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)\r\n   at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)\r\n   at NHib
ernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)\r\n   at Remotion.Linq.QueryableBase`1.GetEnumerator()\r\n   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)"

Can be reproduced by adding the following test to WhereSubqueryTests

[Test(Description = "GH-2471")]
public void TimeSheetsWithStringContainsSubQueryWithAsQueryableAfterWhere()
{
	var query = (from timesheet in db.Timesheets
				where timesheet.Entries.Where(e => e.Comments != null).AsQueryable().Any(e => e.Comments.Contains("testing"))
				select timesheet).ToList();

	Assert.That(query.Count, Is.EqualTo(2));
}
@fredericDelaporte

This comment has been minimized.

@bahusoid

This comment has been minimized.

@lbcsy
Copy link
Author

lbcsy commented Aug 15, 2020

It fails in both 5.2 and 5.3.
I can now identify the error spot, but don't know why and how to overcome it:

The query seems failed with IEnumerable.AsQueryable:

var predicateReadPrivilege = PredicateBuilder.Create<Resource>(x =>
                x.RType.RolePrivileges.Where(a => a.AccessTypeName == accessLevel).AsQueryable().Where(_ => true).Any());// _predicatePrivilegeOnResourceType).Any());

As you can see, even the criteria is a redundant one, it fails, but if I remove the AsQueryable part, it does not throw the exception.

@bahusoid
Copy link
Member

It should work if you apply AsQueryable right after mapped collection x.RType.RolePrivileges.AsQueryable()...

Yeah if such query works in 4.x it looks like a bug. Can be reproduced adding the following test to WhereSubqueryTests

[Test(Description = "GH-2471")]
public void TimeSheetsWithStringContainsSubQueryWithAsQueryableAfterWhere()
{
	var query = (from timesheet in db.Timesheets
				where timesheet.Entries.Where(e => e.Comments != null).AsQueryable().Any(e => e.Comments.Contains("testing"))
				select timesheet).ToList();

	Assert.That(query.Count, Is.EqualTo(2));
}

@bahusoid bahusoid changed the title What is not supported in this query? AsQueryable() on collection throws if applied after Where statement Aug 15, 2020
@bahusoid bahusoid reopened this Aug 15, 2020
@fredericDelaporte

This comment has been minimized.

@bahusoid

This comment has been minimized.

hazzik added a commit to hazzik/nhibernate-core that referenced this issue Aug 30, 2020
@hazzik hazzik added this to the 5.3.3 milestone Aug 30, 2020
hazzik added a commit that referenced this issue Aug 30, 2020
@hazzik hazzik closed this as completed Aug 30, 2020
@fredericDelaporte
Copy link
Member

If this is a regression of 5.0, shouldn't we backport its fix down to 5.0.x?

@hazzik
Copy link
Member

hazzik commented Aug 30, 2020

Yes, we should. But do we want to do it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants