Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

Problem Description
When using .GroupBy(q => new { q.Url, q.ProfileId }.Cube()), the ORM generates an incorrect SQL query. It is expected that GROUP BY CUBE(...) will include both fields (Url and ProfileId), but in the generated query, only the first field (Url) is included.

Example Code (LINQ Query)

var query = _repositoryRequest.Query()
    .GroupBy(q => new { q.Url, q.ProfileId }.Cube())
    .Select(c => new { c.Key.Url, c.Key.ProfileId });

Generated SQL (Incorrect)

GROUP BY CUBE(request0_.url)

Expected SQL (Correct)

GROUP BY CUBE(request0_.url, request0_.profile_id)

CubeHqlGenerator

public class CubeHqlGenerator : BaseHqlGeneratorForMethod
{
    public CubeHqlGenerator()
    {
        SupportedMethods = new[]
        {
            typeof(GroupByExtensions).GetMethod(nameof(GroupByExtensions.Cube))
        };
    }

    public override HqlTreeNode BuildHql(
        MethodInfo method,
        Expression target,
        ReadOnlyCollection<Expression> arguments,
        HqlTreeBuilder treeBuilder,
        IHqlExpressionVisitor visitor)
    {
        if (arguments[0] is NewExpression newExpression)
        {
            var visitedExpressions = newExpression.Arguments
                .Select(expr => visitor.Visit(expr).AsExpression())
                .ToArray();

            if (IsCalledInGroupBy())
            {
                return treeBuilder.MethodCall("CUBE", visitedExpressions);
            }
            else
            {
                return visitedExpressions[0];
            }
        }
        else
        {
            var sourceExpression = visitor.Visit(arguments[0]).AsExpression();

            if (IsCalledInGroupBy())
            {
                return treeBuilder.MethodCall("CUBE", sourceExpression);
            }
            else
            {
                return sourceExpression;
            }
        }
    }
    private bool IsCalledInGroupBy()
    {
        var stackTrace = new StackTrace();
        foreach (var frame in stackTrace.GetFrames())
        {
            var method = frame.GetMethod();
            if (method.Name.Contains("Select"))
                return false;
            if (method.DeclaringType?.ToString().Contains("ProcessGroupBy")??false)
                return true;
        }
        return false;
    }
}
You must be logged in to vote

Replies: 1 comment

Comment options

When registering a Cube function from

        RegisterFunction("CUBE", new SQLFunctionTemplate(NHibernateUtil.String, "CUBE(?1)"));

to

        RegisterFunction("CUBE", new StandardSQLFunction("Cube", null));

it helped me

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
1 participant
Converted from issue

This discussion was converted from issue #3659 on March 10, 2025 10:14.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.