如何在EF 6 Code First中将SQL Server JSON_VALUE函数用于经典.NET [英] How can I use SQL Server JSON_VALUE function in EF 6 Code First for classic .NET

查看:231
本文介绍了如何在EF 6 Code First中将SQL Server JSON_VALUE函数用于经典.NET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I use SQL Server JSON_VALUE function in EF 6 Code First for classic .NET? I found I can do it in EF Core like this:

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();

但是我怎么能在EF 6的经典.NET中实现这一点(在我的案例中是4.6。 1)?

But how can I achieve this in EF 6 in classic .NET (in my case, its 4.6.1)?

推荐答案

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

In classic .NET it's a little bit different, but still possible like this:

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();
}

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

Then, because JSON_VALUE is not defined in the Entity Framework SQL Server provider manifest, you have to create IStoreModelConvention like this:

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();
    }
}

这篇关于如何在EF 6 Code First中将SQL Server JSON_VALUE函数用于经典.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆