EFCore HasDefaultValueSql
今天小伙伴在代码中遇到了有关 HasDefaultValue 的疑问,这里整理澄清下...
在使用 Entity Framework Core (EFCore) 配置实体时,HasDefaultValue 方法会为数据库列设置一个默认值。该默认值的行为取决于以下条件:
1. 配置 HasDefaultValue 的应用场景
HasDefaultValue 主要在以下场景中生效:
- 首次创建表时:当迁移生成
CREATE TABLE的 SQL 脚本时,会在列定义中附带默认值。 - 列被新增到现有表时:在迁移中,新增列时,如果指定了
HasDefaultValue,生成的 SQL 脚本会为新增列设置默认值。
示例:
modelBuilder.Entity<MyEntity>() .Property(e => e.MyColumn) .HasDefaultValue(100);
2. 默认值的应用条件
1) 创建表
如果使用迁移创建表,HasDefaultValue 会为列添加默认值。例如:
CREATE TABLE MyEntity ( Id INT PRIMARY KEY, MyColumn INT DEFAULT 100
);
2) 添加新列
如果表已经存在,且通过迁移为现有表新增列,HasDefaultValue 会生成如下 SQL:
ALTER TABLE MyEntity ADD MyColumn INT DEFAULT 100;
在添加列时,DEFAULT 值会应用到已存在的行。
3) 插入数据
当应用程序通过 EFCore 插入记录,而未显式为列提供值时:
- EFCore 会让数据库使用定义的默认值(依赖于数据库执行)。
注意:EFCore 不会在内存中自动填充默认值到实体属性上。
3. 特殊条件下的行为
1) 与 HasDefaultValueSql 的区别
HasDefaultValue:直接定义一个常量值。HasDefaultValueSql:允许使用 SQL 表达式设置默认值。
例如:
modelBuilder.Entity<MyEntity>() .Property(e => e.MyColumn) .HasDefaultValueSql("GETDATE()");
生成的 SQL:
ALTER TABLE MyEntity ADD MyColumn DATETIME DEFAULT GETDATE();
2) 更新表格时的影响
如果尝试将现有列的默认值修改为另一个值,EFCore 迁移中不会自动生成 ALTER COLUMN SQL,需要手动调整迁移。
3) 在内存中的作用
在运行时,HasDefaultValue 不会对未赋值的属性生效,即在 EFCore 中 HasDefaultValue 仅影响数据库的默认行为。
4. 实际示例与注意事项
代码示例
public class MyEntity
{ public int Id { get; set; } public int MyColumn { get; set; }
} // 配置
modelBuilder.Entity<MyEntity>() .Property(e => e.MyColumn) .HasDefaultValue(100);
生成的迁移代码
migrationBuilder.CreateTable( name: "MyEntity",columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("SqlServer:Identity", "1, 1"), MyColumn = table.Column<int>(nullable: false, defaultValue: 100) }, constraints: table => { table.PrimaryKey("PK_MyEntity", x => x.Id); });
插入数据的行为
- 如果你执行如下代码:
context.MyEntities.Add(new MyEntity { Id = 1 });
context.SaveChanges();
结果中 MyColumn 的值会由数据库设置为 100。
5. 总结
HasDefaultValue 在以下情况下生效:
- 数据库表初次创建时。
- 为现有表新增列时。
- 插入数据时,如果 EFCore 没有为该列赋值,则数据库会自动使用默认值。
如果你想在代码中为未赋值的属性提供默认值,需额外在 C# 类中定义默认值逻辑。
在使用 Entity Framework Core 创建实体并保存到数据库时,如果你为属性赋值了,即使这个值与 HasDefaultValue 配置的值相同,EFCore 的行为取决于以下几个因素:
1. EFCore 的默认行为
- 显式赋值的属性: 即使属性的值与
HasDefaultValue中定义的值相同,EFCore 会将其视为已显式设置。因此,生成的 SQL 插入语句会包含该字段及其值。
示例:
modelBuilder.Entity<MyEntity>() .Property(e => e.MyColumn) .HasDefaultValue(100); var entity = new MyEntity
{ MyColumn = 100 // 显式赋值与默认值相同
}; context.MyEntities.Add(entity);
context.SaveChanges();
生成的 SQL 类似如下:
INSERT INTO MyEntity (MyColumn) VALUES (100);
2. 如何忽略字段
EFCore 只有在属性未显式赋值(即为 null 或默认类型值,如 0 对于整型)时,才会让数据库使用 HasDefaultValue 配置的默认值。
示例:
var entity = new MyEntity(); // 未赋值
MyColumn context.MyEntities.Add(entity);
context.SaveChanges();
生成的 SQL 类似如下:
INSERT INTO MyEntity DEFAULT VALUES;
如果表的 MyColumn 定义了默认值 100,那么数据库会将其设置为 100。
3. 如何避免显式赋值时重复生成字段
如果你希望 EFCore 在插入数据时忽略与默认值相同的显式赋值字段,可以通过以下方式实现:
1) 使用默认值优化器
手动检测属性值是否等于默认值,并在这种情况下将其设置为 null:
var entity = new MyEntity
{ MyColumn = 100 // 与默认值相同
}; if (entity.MyColumn == 100)
{ entity.MyColumn = default; // 设置为默认值
}context.MyEntities.Add(entity);
context.SaveChanges();
生成的 SQL:
INSERT INTO MyEntity DEFAULT VALUES;
2) 自定义 SaveChanges 拦截器
在 DbContext.SaveChanges 方法中拦截并移除与默认值相同的字段:
public override int SaveChanges()
{ foreach (var entry in ChangeTracker.Entries<MyEntity>()) { if (entry.State == EntityState.Added && entry.Entity.MyColumn == 100) {entry.Property(e => e.MyColumn).IsModified = false; } } return base.SaveChanges();
}
4. 总结
- 如果为属性显式赋值,即使值与
HasDefaultValue一样,EFCore 会生成包含该字段的 SQL。 - 要避免生成重复字段,可以在代码逻辑中手动移除默认值的赋值,或使用自定义拦截器动态处理。
- 默认值 (
HasDefaultValue) 仅在未赋值或未提供字段时,由数据库自动填充。
补充:
配置字段为数据库生成
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Example>() .Property(e => e.Age) .HasDefaultValueSql("18");}
归纳一下:
-
HasDefaultValueSql("18")的作用:- 它的主要作用是 在模型构建时告诉 EF Core 该字段在数据库中有默认值。
- EF Core 不会强制使用
HasDefaultValueSql配置的值生成INSERT语句,而是让数据库的默认值(DEFAULT定义)生效。
-
EF Core 生成
INSERT的行为:- 如果字段没有显式赋值(即在代码中未为该字段赋值),EF Core 不会在生成的
INSERT语句中包含该字段,从而依赖数据库在SCHEMA上的DEFAULT值。 - 如果代码中显式赋值了该字段,即使值与
HasDefaultValueSql的配置一致,EF Core 仍会在INSERT语句中包含该字段,并使用显式赋值的值。
- 如果字段没有显式赋值(即在代码中未为该字段赋值),EF Core 不会在生成的
-
实际生效的值:
- 关键是数据库表定义中的
DEFAULT值(由CREATE TABLE或ALTER TABLE设置)。 HasDefaultValueSql中配置的 SQL 只是 帮助 EF Core 在迁移中设置数据库表的默认值,一旦表的SCHEMA定义了默认值,EF Core 就不再干涉。
- 关键是数据库表定义中的
-
HasDefaultValueSql的核心意义:- 它是在 数据库迁移时,帮助生成类似如下的 SQL:
ALTER TABLE Example ADD CONSTRAINT DF_Age DEFAULT 18 FOR Age; - 一旦表的默认值设置完成,EF Core 的
HasDefaultValueSql配置就不再直接影响运行时行为。
- 它是在 数据库迁移时,帮助生成类似如下的 SQL:
示例验证
表定义
CREATE TABLE Example ( Id INT PRIMARY KEY, Name NVARCHAR(50), Age INT DEFAULT 18 );
Fluent API 配置
protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Example>() .Property(e => e.Age) .HasDefaultValueSql("18");
}
插入代码
var example = new Example
{ Name = "Alice" // Age 未赋值 }; context.Examples.Add(example);context.SaveChanges();
}
生成的 SQL:
INSERT INTO Example (Name) VALUES ('Alice'); -- Age 列未包含
数据库最终插入:
Id | Name | Age 1 | Alice | 18
如果数据库默认值改变
假如数据库表的 DEFAULT 定义改为 20,代码和 Fluent API 不变:
生成的 SQL 仍然是:
INSERT INTO Example (Name) VALUES ('Alice'); -- Age 列未包含
但最终插入的值会变为:
Id | Name | Age 1 | Alice | 20
这说明 运行时实际生效的是数据库表的 DEFAULT 值。
总结
HasDefaultValueSql的配置值不会直接影响运行时行为,其作用主要是用于迁移时生成表的默认值定义。- 最终起作用的是数据库表的默认值,而不是
HasDefaultValueSql配置中的值。 - 只要字段未显式赋值,无论是可空还是非可空,EF Core 都会依赖数据库表的默认值生效。
相关文章:
EFCore HasDefaultValueSql
今天小伙伴在代码中遇到了有关 HasDefaultValue 的疑问,这里整理澄清下... 在使用 Entity Framework Core (EFCore) 配置实体时,HasDefaultValue 方法会为数据库列设置一个默认值。该默认值的行为取决于以下条件: 1. 配置 HasDefaultValue 的…...
Win10微调大语言模型ChatGLM2-6B
在《Win10本地部署大语言模型ChatGLM2-6B-CSDN博客》基础上进行,官方文档在这里,参考了这篇文章 首先确保ChatGLM2-6B下的有ptuning AdvertiseGen下载地址1,地址2,文件中数据留几行 模型文件下载地址 (注意࿱…...
什么叫区块链?怎么保证区块链的安全性?
区块链(Blockchain)是一种分布式数据库或账本技术,它通过去中心化的方式记录交易或其他数据,并确保这些记录是安全、透明和不可篡改的。区块链最初是作为比特币(Bitcoin)加密货币的基础技术而被公众所知&am…...
一、智能体强化学习——强化学习基础
1.1 强化学习与深度学习的基本概念 1.1.1 强化学习的核心思想 什么是强化学习? 强化学习(Reinforcement Learning, RL):指在与环境(Environment)的反复交互中,智能体(Agent&#x…...
【DES加密】
什么是DES DES(Data Encryption Standard) 是一种对称加密算法。它的设计目标是提供高度的数据安全性和性能。 DES的概念 DES使用56位的密钥和64位的明文块进行加密。DES算法的分组大小是64位,因此,如果需要加密的明文长度不足64位,需要进…...
.NET中的框架和运行环境
在.NET生态系统中,框架和运行环境是两个不同的概念,它们各自扮演着重要的角色。 下面我将分别介绍.NET中的框架和运行环境,并解释它们之间的区别。 .NET 框架(Frameworks) 框架提供了一套预定义的类库、工具和服务&…...
探索微软 M365 安全:全方位守护数字世界
在当今这个科技呈井喷式飞速发展,数字化浪潮以汹涌澎湃、锐不可当之势席卷全球的时代,企业与个人仿若置身于一片浩瀚无垠、信息奔涌的海洋之中,尽情畅享着技术革新所带来的无穷无尽便利。然而,恰如平静海面下潜藏着暗礁与汹涌暗流,网络安全问题恰似隐匿在暗处、随时可能给…...
深入探索AI核心模型:CNN、RNN、GAN与Transformer
在人工智能的飞速发展中,众多深度学习模型和算法不断涌现,推动了许多领域的进步。特别是在图像识别、自然语言处理、生成建模等方向,AI模型的应用越来越广泛。本文将介绍几种最常用的AI模型,包括卷积神经网络(CNN&…...
Java - Http 通讯
Java - Http 通讯 PS: 1. Http 协议 POST | GET 请求; 2. 支持 报头、报文、参数 自定义配置; 3. GET 返回支持 String | Stream; 4. 相关依赖: <dependency><groupId>org.apache.httpcomponents</groupId><…...
C++ Qt练习项目 QChar功能测试
个人学习笔记 代码仓库 GitCode - 全球开发者的开源社区,开源代码托管平台 新建项目 设计UI 1、拖入group box去掉名字 2、拖入2个LineEdit 3、拖入两个Label 4、拖入两个PushButton 5、点栅格布局 1、拖入GroupBox 2、拖入4个PushButton 3、点栅格布局 1、拖入GroupBo…...
android 官网刷机和线刷
nexus、pixel可使用google官网线上刷机的方法。网址:https://flash.android.com/ 本文使用google线上刷机,将Android14 刷为Android12 以下是失败的线刷经历。 准备工作 下载升级包。https://developers.google.com/android/images?hlzh-cn 注意&…...
二叉树层序遍历 Leetcode102.二叉树的层序遍历
二叉树的层序遍历相当于图论的广度优先搜索,用队列来实现 (二叉树的递归遍历相当于图论的深度优先搜索) 102.二叉树的层序遍历 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右…...
DELTA并联机械手视觉方案荣获2024年度机器人应用典型案例奖
直击现场 2025年1月9日晚,2024深圳市机器人年度评选颁奖典礼在深圳市南山区圣淘沙酒店正式拉开帷幕。本次颁奖活动由中国科学院深圳先进技术研究院指导,深圳市机器人协会与《机器人与智能系统》杂志组织承办。 正运动公司受邀参与此次典礼,…...
Netty 入门学习
前言 学习Spark源码绕不开通信,Spark通信是基于Netty实现的,所以先简单学习总结一下Netty。 Spark 通信历史 最开始: Akka Spark 1.3: 开始引入Netty,为了解决大块数据(如Shuffle)的传输问题 Spark 1.6&…...
Magentic-One、AutoGen、LangGraph、CrewAI 或 OpenAI Swarm:哪种多 AI 代理框架最好?
目录 一、说明 二、 AutoGen-自动生成(微软) 2.1 特征 2.2 局限性 三、 CrewAI 3.1 特征 3.2 限制: 四、LangGraph 4.1 特征: 4.2 限制: 五、OpenAI Swarm 5.1 特征 5.2 限制 六、Magentic-One 6.1 特征 6.2 限制 七、…...
openstack下如何生成centos9 centos10 和Ubuntu24 镜像
如何生成一个centos 10和centos 9 的镜像1. 下载 对应的版本 wget https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-x86_64-10-latest.x86_64.qcow2 wget https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-Gener…...
Kivy App开发之UX控件Slider滑块
在app中可能会调节如音量,亮度等,可以使用Slider来实现,该控件调用方便,兼容性好,滑动平稳。在一些参数设置中,也可以用来调整数值。 支持水平和垂直方向,可以设置默认值,最小及最大值。 使用方法,需用引入Slider类,通过Slider类生成一个滑块并设置相关的样式后,再…...
CSS——22.静态伪类(伪类是选择不同元素状态)
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>静态伪类</title> </head><body><a href"#">我爱学习</a></body> </html>单击链接前的样式 左键单击(且…...
python学opencv|读取图像(三十)使用cv2.getAffineTransform()函数倾斜拉伸图像
【1】引言 前序已经学习了如何平移和旋转缩放图像,相关文章链接为: python学opencv|读取图像(二十七)使用cv2.warpAffine()函数平移图像-CSDN博客 python学opencv|读取图像(二十八࿰…...
Unity3D中基于ILRuntime的组件化开发详解
前言 在Unity3D开发中,组件化开发是一种高效且灵活的软件架构方式。通过将游戏功能拆分为独立的、可重用的组件,开发者可以更容易地管理、扩展和维护代码。而ILRuntime作为一款基于C#的热更新框架,为Unity3D开发者提供了一种高效的热更新和组…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
