Expression tree to SQL with EF Core

后端 未结 2 1339
轻奢々
轻奢々 2020-12-11 04:54

We have a column where JSON data is stored as a string. This JSON data is read and converted through materialization to an IDictionary. Th

2条回答
  •  無奈伤痛
    2020-12-11 05:25

    Until it get "official" support, you can map the JSON_VALUE using the EF Core 2.0 introduced Database scalar function mapping.

    For instance, add the following static method inside your context derived class or in separate static class as below:

    public static class MyDbFunctions
    {
        [DbFunction("JSON_VALUE", "")]
        public static string JsonValue(string source, string path) => throw new NotSupportedException();
    }
    

    and if it is in separate class, add the following to your context OnModelCreating override (not needed if the method is in the context):

    modelBuilder.HasDbFunction(() => MyDbFunctions.JsonValue(default(string), default(string)));
    

    Now you can use it inside your LINQ to Entities queries similar to EF.Functions. Just please note that the function returns string, so in order to trick the compiler to "cast" it to numeric, you can use the double cast technique shown below (tested and working in EF Core 2.1.2):

    var query = db.Set()
        .Where(s => (int)(object)MyDbFunctions.JsonValue(s.Value, "lax $.Name") > 1);
    

    which translates to the desired

    WHERE JSON_VALUE([Value], 'lax $.Name') > 1
    

    Another (probably type safer) way to perform the conversion is to use Convert class methods (surprisingly supported by SqlServer EF Core provider):

    var query = db.Set()
        .Where(s => Convert.ToInt32(MyDbFunctions.JsonValue(s.Value, "lax $.Name")) > 1);
    

    which translates to

    WHERE CONVERT(int, JSON_VALUE([Value], 'lax $.Name')) > 1
    

提交回复
热议问题