如何使用Entity Framework Core直接更新带转换器的属性?
解决方案
针对你遇到的EF Core中使用ExecuteUpdateAsync更新带JSON转换器的复杂类型属性的问题,提供以下几种可行方案:
方案1:查询实体后修改保存
这是最稳妥的方式,单条记录场景下性能影响可忽略:
var targetController = await db.Controllers.FirstOrDefaultAsync(x => x.Id == controller.Id); if (targetController != null) { targetController.ForcedRuntimeParameters = new RuntimeDBParameters(); await db.SaveChangesAsync(); }
直接修改实体实例时,EF的JSON转换器会在SaveChangesAsync阶段自动处理序列化逻辑,不会出现转换异常。
方案2:使用EF Core 7+的EF.JsonSerialize函数
如果项目使用EF Core 7及以上版本,可利用内置JSON序列化函数让EF正确生成SQL表达式:
await db.Controllers .Where(x => x.Id == controller.Id) .ExecuteUpdateAsync(x => x .SetProperty(p => p.ForcedRuntimeParameters, EF.JsonSerialize(new RuntimeDBParameters())) );
此方法需确保复杂类型已正确配置JSON双向转换器,EF会自动将序列化后的JSON字符串映射到目标属性。
方案3:原始SQL(备选方案)
若上述方案不适用,可使用原始SQL更新(以SQL Server为例):
await db.Database.ExecuteSqlInterpolatedAsync( $"UPDATE Controllers SET ForcedRuntimeParameters = '{}' WHERE Id = {controller.Id}" );
异常原因说明
- 第一种更新方式失败:
ExecuteUpdateAsync直接生成批量更新SQL,EF无法将new RuntimeDBParameters()这样的对象实例翻译成对应的SQL表达式。 - 第二种更新方式失败:直接将字符串赋值给强类型属性,EF无法在字符串和
RuntimeDBParameters类型之间进行隐式转换。
内容的提问来源于stack exchange,提问作者ZorgoZ
相关产品推荐
相关产品推荐

