Skip to content
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

HierarchId: Cannot call methods on varchar #30307

Closed
bricelam opened this issue Feb 17, 2023 · 0 comments · Fixed by #30588
Closed

HierarchId: Cannot call methods on varchar #30307

bricelam opened this issue Feb 17, 2023 · 0 comments · Fixed by #30588
Assignees
Labels
area-hierarchyid closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@bricelam
Copy link
Contributor

When calling a method on a constant hierarchyid value...

var query = from p in _db.Patriarchy
            where HierarchyId.Parse("/1/").IsDescendantOf(p.Id)
            select p.Name;

...we generate a text literal and try to call an instance method on it...

SELECT [p].[Name]
FROM [Patriarchy] AS [p]
WHERE '/1/'.IsDescendantOf([p].[Id])

...which results in an error.

SqlException : Cannot call methods on varchar.

Instead, we should generate a hierarchyid value.

SELECT [p].[Name]
FROM [Patriarchy] AS [p]
WHERE hierarchyid::Parse('/1/').IsDescendantOf([p].[Id])

The spatial extension handles this by always generating fully-qualified literals...

builder
.Append(_isGeography ? "geography" : "geometry")
.Append("::")
.Append(defaultSrid ? "Parse" : "STGeomFromText")
.Append("('")
.Append(WKTWriter.ForMicrosoftSqlServer().Write(geometry))
.Append('\'');
if (!defaultSrid)
{
builder
.Append(", ")
.Append(geometry.SRID);
}
builder.Append(')');

...but then simplifies them to string literals when translating methods that take them as parameters:

private IEnumerable<SqlExpression> Simplify(IEnumerable<SqlExpression> arguments, bool isGeography)
{
foreach (var argument in arguments)
{
if (argument is SqlConstantExpression constant
&& constant.Value is Geometry geometry
&& geometry.SRID == (isGeography ? 4326 : 0))
{
yield return _sqlExpressionFactory.Fragment("'" + geometry.AsText() + "'");
continue;
}
yield return argument;
}
}

@ajcvickers ajcvickers added this to the Backlog milestone Mar 2, 2023
bricelam added a commit to bricelam/efcore that referenced this issue Mar 27, 2023
Changes:
- Make HierarchyId compatible with System.Text.Json (resolves efcore/EFCore.SqlServer.HierarchyId#40)
- Add HierarchyId constructors
- Add overloads and clarify docs for GetDescendant
- Improve interop with SqlHierarchyId
- Translate calls on constants (fixes dotnet#30307)
- Don't go through SqlBytes (resolves dotnet#30305)

Part of dotnet#30306
@bricelam bricelam added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Mar 27, 2023
@bricelam bricelam modified the milestones: Backlog, 8.0.0 Mar 27, 2023
@ajcvickers ajcvickers modified the milestones: 8.0.0, 8.0.0-preview4 Apr 20, 2023
@ajcvickers ajcvickers modified the milestones: 8.0.0-preview4, 8.0.0 Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-hierarchyid closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants