Skip to content

Casting to object and back to interface in GroupBy causes error #2857

Closed
@PleasantD

Description

@PleasantD

This is a regression introduced in v5.3.0

I have two different examples of how casting to object and back to an interface of a mapped type cause errors. However they both happen only when one part of the query expression casts to object and another part casts back to the interface of a mapped class. This leads me to think they may be closely related.

Prerequisites

  • Mapped objects have interfaces defined and the Query and casts use the interfaces instead of the mapped types
  • At some point the entities are cast to object and a later part of the query casts them back to the interface type

In our code this casting is done within code that is generating dynamic expressions and queries based on metadata, and hence needs to cast to object at certain steps.

Problem

Casting back to the interface in a GroupBy clause an expression reduction error

Example Code

var query = session.Query<ITimeChunk>()
    .Select(x => new object[] { x })
    .GroupBy(g => new object[] { ((ITimeChunk)g[0]).Issue.Project.Id }, v => (ITimeChunk)v[0])
    .Select(r => new object[] { r.Key, r.Sum(t => (int?)t.Seconds) });

Error

Message: 
    System.ArgumentException : must be reducible node

  Stack Trace: 
    Expression.ReduceAndCheck()
    Expression.ReduceExtensions()
    StackSpiller.RewriteExtensionExpression(Expression expr, Stack stack)
    StackSpiller.RewriteExpression(Expression node, Stack stack)
    StackSpiller.RewriteUnaryExpression(Expression expr, Stack stack)
    StackSpiller.RewriteExpression(Expression node, Stack stack)
    ChildRewriter.Add(Expression node)
    ChildRewriter.Add(IList`1 expressions)
    StackSpiller.RewriteNewArrayExpression(Expression expr, Stack stack)
    StackSpiller.RewriteExpression(Expression node, Stack stack)
    StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
    StackSpiller.Rewrite[T](Expression`1 lambda)
    Expression`1.Accept(StackSpiller spiller)
    LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
    Expression`1.Compile()
    ExpressionToHqlTranslationResults.MergeLambdasAndCompile[TDelegate](IList`1 itemTransformers) line 55
    ExpressionToHqlTranslationResults.ctor(HqlTreeNode statement, IList`1 itemTransformers, IList`1 listTransformers, IList`1 postExecuteTransformers, List`1 additionalCriteria, Type executeResultTypeOverride) line 33
    IntermediateHqlTree.GetTranslation() line 100
    QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root, Nullable`1 rootReturnType) line 106
    NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter) line 97
    ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory) line 20
    QueryExpressionPlan.CreateTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) line 38
    QueryExpressionPlan.ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) line 20
    QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters) line 63
    AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow) line 584
    AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression) line 552
    DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query) line 208
    DefaultQueryProvider.ExecuteList[TResult](Expression expression) line 107
    IEnumerable<T>.GetEnumerator() line 65
    List`1.ctor(IEnumerable`1 collection)
    Enumerable.ToList[TSource](IEnumerable`1 source)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions