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

在Entity Framework .NET 8中如何将数据以JSON对象存入SQL Server?

问题解答

一、直接存储目标JSON格式是否可行?

完全可行。SQL Server 2016及以上版本支持通过NVARCHAR(MAX)字段存储JSON数据,还能借助内置的JSON_VALUE、OPENJSON等函数实现JSON内容的查询与操作。

二、两种主要实现方式

方式1:关系型存储(现有实体类默认行为)

你当前的实体类采用嵌套对象设计,在EF Core Code-First模式下,会自动生成关联表结构:

  • 主表InfieldCoachings:包含Id、InfieldCoachingId、CreatedTime、UpdatedTime等字段
  • 从属表Preparations:包含Id、ReviewCustomerDataBeforeVisit、SetSmartObjectivesForVisit、ComplaintHandlingPlan,以及外键InfieldCoachingId关联主表
  • 从属表Openings:结构与Preparations类似,同样通过外键关联主表

这种方式的优势:

  • 数据结构清晰,支持SQL精确查询与索引优化
  • 符合关系型数据库规范,数据一致性更有保障

方式2:直接存储JSON格式

如果要和你给出的JSON格式完全匹配,可调整实体类,将嵌套对象改为JSON字符串或利用EF Core原生JSON映射:

方案A:手动序列化JSON字符串

namespace Msfa.Api.Entities
{
    public class InfieldCoaching
    {
        public int Id { get; set; }
        public string? InfieldCoachingId { get; set; }
        // 指定SQL字段类型为nvarchar(max)存储JSON
        [Column(TypeName = "nvarchar(max)")]
        public string? Preparation { get; set; }
        [Column(TypeName = "nvarchar(max)")]
        public string? Opening { get; set; }
        public DateTime? CreatedTime { get; set; }
        public DateTime? UpdatedTime { get; set; }
        // 补充Swagger请求中的managers字段
        public List<string>? Managers { get; set; }
    }
}

写入数据时需手动将Preparation/Opening对象序列化为JSON字符串,读取时反序列化为对象。

方案B:EF Core 7+原生JSON映射(推荐)

无需手动序列化,EF Core会自动处理对象与JSON的转换:

namespace Msfa.Api.Entities
{
    public class InfieldCoaching
    {
        public int Id { get; set; }
        public string? InfieldCoachingId { get; set; }
        // 标记为JSON类型,SQL Server自动存储为nvarchar(max)
        [Column(TypeName = "json")]
        public Preparation? Preparation { get; set; }
        [Column(TypeName = "json")]
        public Opening? Opening { get; set; }
        public DateTime? CreatedTime { get; set; }
        public DateTime? UpdatedTime { get; set; }
        public List<string>? Managers { get; set; }
    }

    // 保留原有的嵌套类定义
    public class Preparation
    {
        [Range(1, 5)]
        public int? ReviewCustomerDataBeforeVisit { get; set; }
        [Range(1, 5)]
        public int? SetSmartObjectivesForVisit { get; set; }
        [Range(1, 5)]
        public int? ComplaintHandlingPlan { get; set; }
    }

    public class Opening
    {
        [Range(1, 5)]
        public int? CreateCustomerAttention { get; set; }
        [Range(1, 5)]
        public int? ProductVisibilityChecked { get; set; }
        [Range(1, 5)]
        public int? StockLevelsCounted { get; set; }
    }
}

这种方式支持用SQL函数查询JSON内容,例如:

SELECT JSON_VALUE(Preparation, '$.reviewCustomerDataBeforeVisit') 
FROM InfieldCoachings
WHERE Id = 1

三、Code-First模式操作步骤

针对关系型存储

  1. 在DbContext中添加DbSet:
public class AppDbContext : DbContext
{
    public DbSet<InfieldCoaching> InfieldCoachings { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("你的SQL Server连接字符串");
    }
}
  1. 执行迁移命令生成表结构:
Add-Migration InitialCreate
Update-Database

针对JSON存储

  1. 调整实体类(参考方式2的两种方案)
  2. 配置DbContext中的DbSet
  3. 执行迁移命令生成包含JSON字段的表
  4. 写入数据时,EF Core 7+可直接赋值对象;低版本需手动序列化JSON字符串

四、补充说明

  • 你的Swagger请求示例包含managers字段,但现有实体类未定义,需在InfieldCoaching中添加public List<string>? Managers { get; set; }才能接收该参数
  • 关系型存储适合结构稳定、需频繁查询单个字段的场景;JSON存储适合结构灵活、无需频繁拆解查询的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:22:45