当前位置: 首页 > news >正文

EFCore HasDefaultValueSql (续2 HasComputedColumnSql)

前情:EFCore HasDefaultValueSql

EFCore HasDefaultValueSql (续1 ValueGeneratedOnAdd)-CSDN博客

小伙伴在使用 HasDefaultValueSql 时,对相关的 ValueGeneratedOnAdd, HasComputedColumnSql  也有了疑问:

HasComputedColumnSql  

对于计算列,无论是插入还是编辑,应该由数据库的 SCHEMA 上的计算逻辑负责。对于这种场景,ValueGeneratedOnAdd 并不适合,因为它只针对在插入时生成的值,而计算列可能涉及插入和更新两个阶段的行为。

EF Core 中,针对计算列的正确配置应该是使用 ValueGeneratedOnAddOrUpdateHasComputedColumnSql,以下是详细说明。


1. HasComputedColumnSql

HasComputedColumnSql 是用于配置 计算列 的 Fluent API,告诉 EF Core 该列的值是由数据库根据 SQL 逻辑自动计算的。

核心特点
  • 专用于计算列:用于设置数据库的 GENERATED ALWAYS AS 或等效功能。
  • 插入和更新行为:EF Core 不会尝试在插入或更新中显式写入该列的值,而是完全依赖数据库的计算逻辑。
  • 适用场景
    • 表达式列(如计算两个字段的总和)。
    • 基于函数、触发器等逻辑动态生成值的列。
使用示例

假设数据库有一个计算列 TotalPrice,定义为 Price * Quantity

数据库表定义:

CREATE TABLE Orders ( Id INT PRIMARY KEY, Price DECIMAL(10, 2), Quantity INT, TotalPrice AS Price * Quantity PERSISTED 
); 

EF Core 配置:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ modelBuilder.Entity<Order>() .Property(o => o.TotalPrice) .HasComputedColumnSql("[Price] * [Quantity]", stored: true); 
} 

解释:

  • [Price] * [Quantity] 是计算逻辑。
  • stored: true 表示这是一个 持久化计算列PERSISTED),结果会存储在数据库中。如果是非持久化列,则省略 stored: true
插入和更新行为
  • 插入时,INSERT 语句中不会包含 TotalPrice
  • 更新时,UPDATE 语句中也不会包含 TotalPrice
  • 示例生成的 SQL:
    INSERT INTO Orders (Price, Quantity) VALUES (10.00, 2); 

2. ValueGeneratedOnAddOrUpdate

ValueGeneratedOnAddOrUpdate 表示字段的值可以在 插入更新 时由数据库生成。这在某些场景下也适用于计算列,但通常需要结合 HasComputedColumnSql 使用。

核心特点
  • 同时覆盖 插入更新 的场景。
  • 不会显式插入或更新字段,EF Core 会假定该字段的值由数据库生成。
使用场景

如果 EF Core 的 HasComputedColumnSql 不适用(如动态触发器逻辑),可以单独使用 ValueGeneratedOnAddOrUpdate

示例配置:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ modelBuilder.Entity<Order>() .Property(o => o.TotalPrice) .ValueGeneratedOnAddOrUpdate(); 
} 

此时,TotalPrice 的计算完全依赖数据库逻辑,EF Core 只会在需要时从数据库中重新加载值。


对比和选择

特性HasComputedColumnSqlValueGeneratedOnAddOrUpdate
核心用途显式配置计算列的 SQL 表达式。泛化的生成策略,适用于动态生成值的场景。
插入行为不会包含该列,依赖数据库计算。不会包含该列,依赖数据库生成。
更新行为不会包含该列,依赖数据库计算。不会包含该列,依赖数据库更新或触发器生成。
适用场景数据库定义了明确的计算逻辑(如表达式列)。动态值生成逻辑,如触发器或非表达式列。

总结

  • 如果字段是严格意义上的 计算列,应使用 HasComputedColumnSql
  • 如果字段依赖动态触发器逻辑,但没有明确的计算公式,考虑使用 ValueGeneratedOnAddOrUpdate
  • 通常情况下,HasComputedColumnSql 是计算列的首选方式,因为它与数据库 SCHEMA 定义直接对应,行为明确且易于维护。

补充,mysql的计算列文档:MySQL :: MySQL 8.4 Reference Manual :: 15.1.20.8 CREATE TABLE and Generated Columns




http://www.lryc.cn/news/518811.html

相关文章:

  • 阿里巴巴TransmittableThreadLocal使用指南
  • ubuntu20下编译linux1.0 (part1)
  • 欧拉公式和傅里叶变换
  • Jenkins内修改allure报告名称
  • 30天开发操作系统 第 12 天 -- 定时器 v1.0
  • Ubuntu | PostgreSQL | 解决 ERROR: `xmllint` is missing on your system.
  • uniapp使用chooseLocation安卓篇
  • 《PC 上的开源神经网络多模态模型:开启智能交互新时代》
  • Apache JMeter 压力测试使用说明
  • 腾讯云AI代码助手编程挑战赛-知识百科AI
  • 【SpringAOP】Spring AOP 底层逻辑:切点表达式与原理简明阐述
  • HTTP-响应协议
  • SQL进阶实战技巧:即时订单比例问题
  • 什么是端口
  • 【Flutter】使用ScrollController配合EasyRefresh实现列表预加载:在还未滑动到底部时加载下一页数据
  • 【2025 Rust学习 --- 11 实用工具特型01】
  • 网络安全基础以及概念
  • windows和linux的抓包方式
  • 【Uniapp-Vue3】v-if条件渲染及v-show的选择对比
  • 宝塔面板使用 GoAccess Web 日志分析教程
  • Windows 安装 Docker 和 Docker Compose
  • arcgis中用python脚本批量给多个要素类的相同字段赋值
  • 目标客户营销(ABM)结合开源AI智能名片2+1链动模式S2B2C商城小程序的策略与实践
  • 《异步编程之美》— 全栈修仙《Java 8 CompletableFuture 对比 ES6 Promise 以及Spring @Async》
  • 新模型设计:Hybrid Quantum-Classical Neural Network (HQCNN) for Image Classification
  • iOS 中spring动画的使用
  • 初学stm32 --- DMA直接存储器
  • 校医院挂号及预约 APP 的设计与实现
  • 代理模式详解与应用
  • Model-based RL自动出价算法的演进之路