【问题标题】:How can I use SQL Server JSON_VALUE function in EF 6 Code First for classic .NET如何在 EF 6 Code First 中为经典 .NET 使用 SQL Server JSON_VALUE 函数
【发布时间】:2018-05-23 14:14:36
【问题描述】:

如何在经典 .NET 的 EF 6 Code First 中使用 SQL Server JSON_VALUE 函数?我发现我可以像这样在 EF Core 中做到这一点:

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

// In OnModelCreating
modelBuilder.HasDbFunction(typeof(JsonExtensions).GetMethod(nameof(JsonExtensions.JsonValue)))
    .HasName("JSON_VALUE")
    .HasSchema("");

// And then the usage
var result = db.Blogs.Select(t => JsonExtensions.JsonValue(t.Log, "$.JsonPropertyName")).ToArray();

但是如何在经典 .NET 的 EF 6 中实现这一点(在我的例子中,它是 4.6.1)?

【问题讨论】:

    标签: c# json sql-server entity-framework dbfunctions


    【解决方案1】:

    在经典的 .NET 中它有点不同,但仍然可以像这样:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Add(new RegisterJsonValueFunctionConvention());
    }
    
    // Than define your function
    [DbFunction("CodeFirstDatabaseSchema", "JSON_VALUE")]
    public static string JsonValue(string expression, string path)
    {
        throw new NotSupportedException();
    }
    

    然后,因为 JSON_VALUE 未在实体框架 SQL Server 提供程序清单中定义,您必须像这样创建 IStoreModelConvention:

    public class RegisterJsonValueFunctionConvention : IStoreModelConvention<EdmModel>
    {
        public void Apply(EdmModel item, DbModel model)
        {
            var expressionParameter = FunctionParameter.Create("expression", GetStorePrimitiveType(model, PrimitiveTypeKind.String), ParameterMode.In);
            var pathParameter = FunctionParameter.Create("path", GetStorePrimitiveType(model, PrimitiveTypeKind.String), ParameterMode.In);
            var returnValue = FunctionParameter.Create("result", GetStorePrimitiveType(model, PrimitiveTypeKind.String), ParameterMode.ReturnValue);
            CreateAndAddFunction(item, "JSON_VALUE", new[] { expressionParameter, pathParameter }, new[] { returnValue });
        }
    
        protected EdmFunction CreateAndAddFunction(EdmModel item, string name, IList<FunctionParameter> parameters, IList<FunctionParameter> returnValues)
        {
            var payload = new EdmFunctionPayload { StoreFunctionName = name, Parameters = parameters, ReturnParameters = returnValues, Schema =  GetDefaultSchema(item), IsBuiltIn = true };
            var function = EdmFunction.Create(name, GetDefaultNamespace(item), item.DataSpace, payload, null);
            item.AddItem(function);
            return function;
        }
    
        protected EdmType GetStorePrimitiveType(DbModel model, PrimitiveTypeKind typeKind)
        {
            return model.ProviderManifest.GetStoreType(TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(typeKind))).EdmType;
        }
    
        protected string GetDefaultNamespace(EdmModel layerModel)
        {
            return layerModel.GlobalItems.OfType<EdmType>().Select(t => t.NamespaceName).Distinct().Single();
        }
    
        protected string GetDefaultSchema(EdmModel layerModel)
        {
            return layerModel.Container.EntitySets.Select(s => s.Schema).Distinct().SingleOrDefault();
        }
    }
    

    【讨论】:

    • 这与 .NET Core 或“经典”.NET 无关。 EF Core 可以在两种运行时上运行
    • 你能举例说明你是如何使用它的吗?我在设置表达式参数值时遇到问题。
    • 您的问题解决了吗?抱歉,我没有更多示例代码和数据库,必须从头开始创建。
    • @walkerbox 已经完美地拼写了所有内容。如何使用它的示例。假设:静态方法JsonValue 位于某种全局命名空间中。包含 JSON 的列在您的 EF 模型中被命名为“Json”。 context.MyTable.Select(row =&gt; JsonValue(row.Json, "$.MyJsonSelector")
    • @walkerbox 非常感谢您提供的详细步骤。但是我遇到了问题,我需要将字符串转换(或转换)为不同的数据类型,例如 BIT。如何实现 CAST(JSON_VALUE(json, "$.MyJsonSelector") as bit)?提前感谢您为我指明了实现这一目标的方向。
    【解决方案2】:

    我不确定它是否适用于 Entity-Framework 6,但可能值得一提 Impatient

    它允许您对 json_value 列等执行 LINQ 查询。

    【讨论】:

    • 我不认为你有一个例子。我一直在筛选文档和测试,正在努力寻找一个
    猜你喜欢
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多