-
Notifications
You must be signed in to change notification settings - Fork 932
Closed
Labels
Description
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;
}
}