You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 6中OPENJSON自定义翻译:传递列名而非字符串的实现

解决方案

方案1:注册表值函数+EF.Property获取原始列

EF Core 6支持注册SQL内置的表值函数,结合EF.Property可以直接映射到数据库列,避免参数被转成字符串字面量。

  1. 定义表值函数的静态声明
    创建一个静态类,声明对应SQL OPENJSON的方法,标记为EF内置函数:
public static class JsonDbFunctions
{
    // 映射到SQL的OPENJSON表值函数
    [DbFunction("OPENJSON", IsBuiltIn = true)]
    public static IEnumerable<JsonElement> OpenJson(string jsonColumn)
    {
        // 仅用于EF翻译,运行时不会执行
        throw new NotImplementedException("仅支持EF Core查询翻译场景");
    }
}
  1. 在DbContext中注册函数
    在OnModelCreating方法里注册这个表值函数,让EF识别它:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    
    var openJsonMethod = typeof(JsonDbFunctions).GetMethod(nameof(JsonDbFunctions.OpenJson));
    modelBuilder.HasDbFunction(openJsonMethod)
        .HasName("OPENJSON")
        .IsBuiltIn();
}
  1. 编写查询逻辑
    使用EF.Property<string>(item, nameof(Item.Sections))获取Sections列的原始字符串值(绕开EF对IEnumerable<Section>的映射),传给自定义的OpenJson方法,再结合JSON_VALUE做过滤:
var targetValue = "需要匹配的内容";

var query = dbContext.Items
    .Where(item => JsonDbFunctions.OpenJson(EF.Property<string>(item, nameof(Item.Sections)))
        .Any(jsonSection => EF.Functions.JsonValue(jsonSection.GetRawText(), "$.你的属性名") == targetValue));

var result = await query.ToListAsync();

这段代码会生成正确的SQL:

SELECT [i].[Id], [i].[Sections], ...
FROM [Items] AS [i]
WHERE EXISTS (
    SELECT 1
    FROM OPENJSON([i].[Sections]) AS [j]
    WHERE JSON_VALUE([j].[value], N'$.你的属性名') = N'需要匹配的内容'
)

方案2:直接使用FromSqlRaw(快速临时方案)

如果不想修改DbContext配置,可以直接用原生SQL查询,再映射回实体:

var targetValue = "需要匹配的内容";

var result = await dbContext.Items
    .FromSqlRaw(@"
        SELECT * FROM Items
        WHERE EXISTS (
            SELECT 1 FROM OPENJSON(Sections) j
            WHERE JSON_VALUE(j.value, '$.你的属性名') = {0}
        )", targetValue)
    .ToListAsync();

关键说明

  • EF.Property<T>是核心:它告诉EF直接访问实体对应的数据库列,而非映射后的IEnumerable<Section>属性,因此不会生成字符串字面量'Sections'。
  • 表值函数注册:EF Core 6对内置表值函数的翻译支持完善,注册后可以无缝结合LINQ查询使用。

内容的提问来源于stack exchange,提问作者vgru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:35:19