Skip to content

Support MemberInit expression in group by #2221

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
Molinware opened this issue Sep 18, 2019 · 4 comments · Fixed by #2322
Closed

Support MemberInit expression in group by #2221

Molinware opened this issue Sep 18, 2019 · 4 comments · Fixed by #2322

Comments

@Molinware
Copy link

Molinware commented Sep 18, 2019

Execute this query gives the following exception:

public class Company
{
    public int Id { get; set; }
    public string Description { get; set; }
}

public class CompanyDto
{
    public int Id { get; set; }
    public string Description { get; set; }
}

var query = session.Query<Company>()
    .Select(x =>
        new CompanyDto()
	{
	    Id = x.Id,
	    Description = x.Description,
	})
    .GroupBy(x => x.Id)
    .Select(x =>
        new CompanyDto()
	{
	    Id = x.Key,
	    Description = x.Max(y => y.Description),
	});

query.ToList()
The method or operation is not implemented
[StackTrace]
in NHibernate.Linq.GroupBy.GroupBySelectClauseRewriter.VisitMember(MemberExpression expression)
in NHibernate.Linq.Expressions.NhAggregatedExpression.VisitChildren(ExpressionVisitor visitor)
in NHibernate.Linq.Expressions.NhExpression.Accept(ExpressionVisitor visitor)
in NHibernate.Linq.GroupBy.GroupBySelectClauseRewriter.ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
in NHibernate.Linq.GroupBy.GroupBySelectClauseRewriter.VisitSubQuery(SubQueryExpression expression)
in System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
in System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection`1 nodes, Func`2 elementVisitor)
in System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
in NHibernate.Linq.GroupBy.GroupBySelectClauseRewriter.ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
in NHibernate.Linq.GroupBy.AggregatingGroupByRewriter.<>c__DisplayClass2_0.<FlattenSubQuery>b__0(Expression s)
in Remotion.Linq.Clauses.SelectClause.TransformExpressions(Func`2 transformation)
in NHibernate.Linq.GroupBy.AggregatingGroupByRewriter.FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy)
in NHibernate.Linq.GroupBy.AggregatingGroupByRewriter.ReWrite(QueryModel queryModel)
in NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root, Nullable`1 rootReturnType)
in NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)
in NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
in NHibernate.Engine.Query.QueryExpressionPlan.CreateTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
in NHibernate.Engine.Query.QueryExpressionPlan..ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
in NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
in NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
in NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
in NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query)
in NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
in NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
in Remotion.Linq.QueryableBase`1.GetEnumerator()
in System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
in System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
@Molinware
Copy link
Author

It looks like making a small change on the "GroupBySelectClauseRewriter" class resolves the problem, but i don't know what problems can it cause:

protected override Expression VisitMember(MemberExpression expression)
{
    if (!IsMemberOfModel(expression))
    {
        return base.VisitMember(expression);
    }

    if (expression.IsGroupingKeyOf(_groupBy))
    {
        // If we have referenced the Key, then return the nominated key expression
	return _nominatedKeySelector;
    }

    var elementSelector = _groupBy.ElementSelector;

    if ((elementSelector is MemberExpression) || (elementSelector is QuerySourceReferenceExpression))
    {
        // If ElementSelector is MemberExpression, just return
        return base.VisitMember(expression);
    }

    if ((elementSelector is NewExpression || elementSelector.NodeType == ExpressionType.Convert)
        && elementSelector.Type == expression.Expression.Type)
    {
        //TODO: probably we should check this with a visitor
        return Expression.MakeMemberAccess(elementSelector, expression.Member);
    }

    throw new NotImplementedException();
}

Change:

throw new NotImplementedException();

To:

return Expression.MakeMemberAccess(elementSelector, expression.Member);

@Molinware
Copy link
Author

So... It's been 5 months...

@fredericDelaporte
Copy link
Member

This is open-source and volunteer based work. You are welcome to contribute a PR, following contributing guidelines.
Otherwise you will have to wait for someone having time to handle this.

@fairking
Copy link

fairking commented Mar 27, 2020

Change: throw new NotImplementedException();
To: return Expression.MakeMemberAccess(elementSelector, expression.Member);

I tried to add this line on the latest master and ended up with another error by executing odata request '/odata/tickets?$apply=groupby((priority))':

System.NotSupportedException
  HResult=0x80131515
  Message=MemberInit
  Source=NHibernate
  StackTrace:
   at NHibernate.Linq.Visitors.HqlGeneratorExpressionVisitor.VisitExpression(Expression expression) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionVisitor.cs:line 149
   at NHibernate.Linq.Visitors.HqlGeneratorExpressionVisitor.<VisitNewArrayExpression>b__35_0(Expression exp) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionVisitor.cs:line 590
   at NHibernate.Util.EnumerableExtensions.ToArray[TInput,TOutput](ICollection`1 input, Func`2 converter) in C:\Code\nhibernate-core\src\NHibernate\Util\EnumerableExtensions.cs:line 49
   at NHibernate.Linq.Visitors.HqlGeneratorExpressionVisitor.VisitNewArrayExpression(NewArrayExpression expression) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionVisitor.cs:line 590
   at NHibernate.Linq.Visitors.HqlGeneratorExpressionVisitor.VisitExpression(Expression expression) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionVisitor.cs:line 103
   at NHibernate.Linq.Visitors.HqlGeneratorExpressionVisitor.Visit(Expression expression) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionVisitor.cs:line 42
   at NHibernate.Linq.Visitors.HqlGeneratorExpressionVisitor.Visit(Expression expression, VisitorParameters parameters) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionVisitor.cs:line 28
   at NHibernate.Linq.Visitors.ResultOperatorProcessors.ProcessGroupBy.<>c__DisplayClass0_0.<Process>b__0(Expression k) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\ResultOperatorProcessors\ProcessGroupBy.cs:line 19
   at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at NHibernate.Linq.Visitors.ResultOperatorProcessors.ProcessGroupBy.Process(GroupResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\ResultOperatorProcessors\ProcessGroupBy.cs:line 21
   at NHibernate.Linq.Visitors.ResultOperatorProcessors.ResultOperatorProcessor`1.Process(ResultOperatorBase resultOperator, QueryModelVisitor queryModel, IntermediateHqlTree tree) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\ResultOperatorProcessors\ResultOperatorProcessor.cs:line 17
   at NHibernate.Linq.Visitors.ResultOperatorProcessors.ResultOperatorMap.Process(ResultOperatorBase resultOperator, QueryModelVisitor queryModel, IntermediateHqlTree tree) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\ResultOperatorProcessors\ResultOperatorMap.cs:line 24
   at NHibernate.Linq.Visitors.QueryModelVisitor.VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, Int32 index) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\QueryModelVisitor.cs:line 379
   at Remotion.Linq.Clauses.ResultOperatorBase.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
   at Remotion.Linq.QueryModelVisitorBase.VisitResultOperators(ObservableCollection`1 resultOperators, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at NHibernate.Linq.Visitors.QueryModelVisitor.Visit() in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\QueryModelVisitor.cs:line 163
   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root, Nullable`1 rootReturnType) in C:\Code\nhibernate-core\src\NHibernate\Linq\Visitors\QueryModelVisitor.cs:line 104
   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter) in C:\Code\nhibernate-core\src\NHibernate\Linq\NhLinqExpression.cs:line 84
   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory) in C:\Code\nhibernate-core\src\NHibernate\Hql\Ast\ANTLR\ASTQueryTranslatorFactory.cs:line 19
   at NHibernate.Engine.Query.QueryExpressionPlan.CreateTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) in C:\Code\nhibernate-core\src\NHibernate\Engine\Query\QueryExpressionPlan.cs:line 38
   at NHibernate.Engine.Query.QueryExpressionPlan..ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) in C:\Code\nhibernate-core\src\NHibernate\Engine\Query\QueryExpressionPlan.cs:line 20
   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters) in C:\Code\nhibernate-core\src\NHibernate\Engine\Query\QueryPlanCache.cs:line 63
   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow) in C:\Code\nhibernate-core\src\NHibernate\Impl\AbstractSessionImpl.cs:line 539
   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression) in C:\Code\nhibernate-core\src\NHibernate\Impl\AbstractSessionImpl.cs:line 507
   at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query) in C:\Code\nhibernate-core\src\NHibernate\Linq\DefaultQueryProvider.cs:line 191
   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression) in C:\Code\nhibernate-core\src\NHibernate\Linq\DefaultQueryProvider.cs:line 93
   at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression) in C:\Code\nhibernate-core\src\NHibernate\Linq\DefaultQueryProvider.cs:line 100
   at Remotion.Linq.QueryableBase`1.System.Collections.IEnumerable.GetEnumerator()
   at System.Text.Json.JsonSerializer.HandleEnumerable(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
   at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.<WriteAsyncCore>d__50.MoveNext()

@fredericDelaporte fredericDelaporte added this to the 5.3 milestone Apr 14, 2020
@fredericDelaporte fredericDelaporte changed the title GroupBySelectClauseRewriter NotImplementedException Support MemberInit expression in group by Apr 14, 2020
georgi-yakimov pushed a commit to georgi-yakimov/nhibernate-core that referenced this issue Apr 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants