question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is `NotParameterizedAttribute` working as expected?

See original GitHub issue

I’m not sure whether it’s a bug report or just misunderstanding, but based on the attribute name and/or xmldocs, it should not be working correctly.

Consider the following setup:

// ...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDbFunction(() => FromPostgis(default, default))
        .HasTranslation(CustomSqlTranslatingExpressionVisitor.TranslateFromPostgis);
// ...
}

public virtual byte[] ToPostgis([NotParameterized] GeoFormat geoFormat, [NotParameterized] string data) =>
    throw new NotSupportedException(_errorMessage);

We have such query:

var result = await _context.WithoutEntity
    .Select(_ => new PlainGeometry
    {
        Format = query.Format,
        Data = _context.FromPostgis(query.Format,
            _context.ST_Difference(
                _context.ST_MakeValid(query.Geometry),
                _context.ST_MakeValid(query.CutterGeometry)))
    })
    .FirstOrDefaultAsync();

In the translation method, the very beginning:

public static SqlExpression TranslateFromPostgis(IReadOnlyCollection<SqlExpression> expressions)
{
    var geoFormat = (GeoFormat) ((SqlConstantExpression) expressions.First()).Value;
    // ...
}

The above throws InvalidCastException because it’s not possible to cast from SqlParameterExpression to SqlConstantExpression. Since we need to have the value for our translation, we are forced to change most of our queries to never include the same variable/property twice in the same query (which is good enough for workaround, but we’d rather not do that), e.g.:

var result = await _context.WithoutEntity
    .Select(_ => new PlainGeometry
    {
        Data = _context.FromPostgis(query.Format,
            _context.ST_Difference(
                _context.ST_MakeValid(query.Geometry),
                _context.ST_MakeValid(query.CutterGeometry)))
    })
    .FirstOrDefaultAsync();
result.Format = query.Format;

As soon as the same variable or property is used multiple times in the same query, expression gets parameterized.

So my question is… Does the NotParameterizedAttribute actually work as expected? Should it not force function argument to not be SqlParameterExpression, regardless of whether the same value is used in multiple places?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
smitpatelcommented, Apr 23, 2021

The attribute is supposed to be used when a closure dependent variable is used as a parameter and it shouldn’t be generated as a query parameter. There is no guarantee of it being SqlConstantExpression always. Without looking at repro code, we cannot say that it should be SqlConstantExpression always.

0reactions
rojicommented, Apr 27, 2021

@smitpatel do we want to use this to track the previous bug (or deup it with another issue)?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Allow [NotParameterized] to work for query filters #25630
No. This requires something beyond NotParameterizedAttribute . If we don't create parameter then we cannot cache the query plan.
Read more >
NotParameterizedAttribute Class
Signals that custom LINQ operator parameter should not be parameterized during query compilation.
Read more >
sql - EXEC sp_executesql framed from "FromSQLRaw" not ...
I'm trying to get some details from Database using our EF core application with the help of "fromSQLRaw" function by framing the Query....
Read more >
Change Coupling
CodeScene - The history of your code will decide its future.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found