linq2db / linq2db.EntityFrameworkCore

Bring power of Linq To DB to Entity Framework Core projects
MIT License
462 stars 38 forks source link

Sql Function Translation Issues #87

Closed npbenjohnson closed 3 years ago

npbenjohnson commented 3 years ago

Thanks for maintaining this library, I just started using it yesterday and am a little bit in disbelief at how easy it was to drop into an EFCore Project.

I'm working with SqlServer Json functionality and hit a few issues with dbfunctions.

  1. It appears .ToLinqToDB() doesn't pick up functions that are mapped via expression.

This does not work, it renders with the name "JsonValue":

modelBuilder.HasDbFunction(typeof(DbJson).GetMethod(nameof(DbJson.JsonValue)))
                .HasTranslation(e => SqlFunctionExpression.Create(
                    "JSON_VALUE", e, typeof(string), null));

This does work, so I do have a workaround for now since my method signature didn't actually need to be mapped:

modelBuilder.HasDbFunction(typeof(DbJson).GetMethod(nameof(DbJson.JsonValue))).HasName("JSON_VALUE");
// --- other file
[Expression("JSON_VALUE({column},{path})", ServerSideOnly = true)]
public static string JsonValue(string column, [NotParameterized] string path)
{
    throw new NotSupportedException();
}
  1. I don't know if there is interplay between mapping functions using Sql.ExpressionAttribute / Sql.FunctionAttribute / Sql.ExtensionsAttribute, but I first tried to fix it by adding those to the method, and they appear to do nothing if you put them on a method that the DbContext is already mapping, but I was expecting them to override the normal DbContext behavior.

  2. The NotParameterized attribute from EfCore appears to not be respected:

    public static string JsonValue(string column, [NotParameterized] string path)
    {
    throw new NotSupportedException();
    }

    renders to sql like

    JSON_VALUE([a_Product].[Json], @path_1)

    but I read it is important that the "path" argument doesn't get parameterized so that the query optimizer will to use computed Json indexes. If you have any ideas on a workaround that could force rendering it like

    JSON_VALUE([a_Product].[Json], N'Actual String Value Of "path"')

    please let me know because this one has me stumped.

sdanyliv commented 3 years ago

Thanks, will check that case.