代码之家  ›  专栏  ›  技术社区  ›  Jonatan Dragon

对于Classic.net,如何在ef 6代码中首先使用SQL Server json_value函数

  •  6
  • Jonatan Dragon  · 技术社区  · 7 年前

    对于Classic.net,如何首先使用EF6代码中的SQL Server JSON U值函数?我发现我可以在 EF核心 这样地:

    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中,我如何在EF6中实现这一点(在我的例子中,它是4.6.1)?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Jonatan Dragon    7 年前

    在经典的.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();
    }
    

    然后,由于在实体框架SQL Server提供程序清单中没有定义json_值,因此必须创建如下的istorreconvention:

    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();
        }
    }
    
        2
  •  1
  •   Shimmy Weitzhandler 500 - Internal Server Error    6 年前

    我不确定它是否适用于实体框架6,但可能值得一提 Impatient .

    它允许您在 json_value 列等。