EF Core 深入学习

news/2025/11/27 13:40:14/文章来源:https://www.cnblogs.com/qinganning/p/19277167

EF Core操作实体属性的内部机制

  • 核心概念: EF Core 的直接字段访问

  • EF Core 在操作实体属性时,会尽量绕过属性的 getter/setter,直接操作背后的私有字段

    • 为什么要这么做?基于性能和对特殊功能支持的考虑
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApp1
{public class Person{public long Id { get; set; }// public string Name { get; set; } // 不用简写形式,更能验证结论private string _name; // 按照结论,会直接读_name,而不会先执行Name的get和set的逻辑public string Name{get {Console.WriteLine("get被调用了!");return _name;}set {Console.WriteLine("set被调用了!");_name = value;}}}
}
  • 数据库配置和主程序代码如下
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;
namespace ConsoleApp1
{public class MyDbContext : DbContext{public DbSet<Person> Persons { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){base.OnConfiguring(optionsBuilder);// 添加 TrustServerCertificate=true 解决证书问题optionsBuilder.UseSqlServer("Server=.;Database=ddd1;Trusted_Connection=True;TrustServerCertificate=true;");}}
}// Program.cs
using ConsoleApp1;Person p1 = new();
p1.Name = "yzk"; // 这里调用 setter,输出 "set被调用了!"
using var ctx = new MyDbContext();
ctx.Persons.Add(p1);
ctx.SaveChanges(); // 这里应该调用 getter,但实际没有!
  • 本次程序的运行结果
set被调用了!
  • 按照预想的结果,当执行完ctx.SaveChanges()后,控制台应该会打印get被调用了,然而并没有发生
    • 原因: EF Core 在保存时直接读取 _name 字段,没有通过 Name 属性的 getter。
using ConsoleApp1;//Person p1 = new();
//p1.Name = "yzk";
//using var ctx = new MyDbContext();
//ctx.Persons.Add(p1);
//ctx.SaveChanges();using var ctx = new MyDbContext();
Person p1 = ctx.Persons.First();
Console.WriteLine(p1.Id);
Console.WriteLine(p1.Name);  // 这里调用 getter
  • 程序运行结果
1
get被调用了!
yzk
  • 按理说,执行了两次Console,那么应该调用两次get,而事实上只调用了一次!
    • EF Core 在创建对象时直接设置 _name 字段,没有通过 setter
    • 只有当我们显式访问 p1.Name 时才调用 getter
  • 再次实验,当把字段从 _name 改为 xiaoming 后(主程序不变)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApp1
{public class Person{public long Id { get; set; }private string xiaoming;public string Name{get {Console.WriteLine("get被调用了!");return xiaoming;}set {Console.WriteLine("set被调用了!");xiaoming = value;}}}
}
  • 运行结果如下
set被调用了!      // 创建对象时通过 setter
get被调用了!      // EF Core 内部跟踪时调用 getter  
get被调用了!      // 再次内部调用
1
get被调用了!      // 我们显式访问时调用
yzk

原理分析

EF Core 的字段发现规则

EF Core 按照以下顺序寻找匹配的字段:

  1. _<propertyName>(如 _name
  2. _<PropertyName>(如 _Name
  3. <propertyName>(如 name
  4. <PropertyName>(如 Name

为什么会这样设计?

  1. 性能优化:直接访问字段比通过属性访问器更快
  2. 绕过业务逻辑:避免属性 setter 中的验证逻辑影响数据加载
  3. 跟踪变化:EF Core 需要直接监控字段值的变化

需要避免的情况

public string Name
{get { return _name; }set { if(string.IsNullOrEmpty(value))throw new Exception("名称不能为空"); // EF Core 加载数据时会触发异常!_name = value; }
}

推荐的实践

// 如果需要在 setter 中添加逻辑,要确保不影响 EF Core 的数据加载
public string Name
{get { return _name; }set { // 避免在这里添加严格的验证逻辑_name = value; // 或者添加不阻碍数据加载的逻辑}
}

总结

  • 数据加载时:EF Core 尽量直接操作字段,不触发属性逻辑
  • 显式访问时:才会调用我们定义的 getter/setter
  • 字段命名:会影响 EF Core 的行为方式

意义: 理解这个机制对于编写正确的 EF Core 实体类和避免潜在的 bug 非常重要!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/978393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unit 4 Intensive Listening 2

Part 1 Before I describe those studies, lets talk about how we are defining art. describe vt. 描写, 叙述 defining adj. 最典型的, 起决定性作用的

深入解析:51单片机基础-IO扩展(并转串 74HC165)

深入解析:51单片机基础-IO扩展(并转串 74HC165)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

实用指南:如何在 React 中实现键盘快捷键管理器以提升用户体验

实用指南:如何在 React 中实现键盘快捷键管理器以提升用户体验2025-11-27 13:34 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !impo…

2025年十大GEO源头厂家口碑排行榜,南方网通GEO源头厂

为帮助企业精准筛选技术可靠、口碑优质的GEO源头厂家,避免踩中技术断层、服务脱节的坑,我们从技术原创性(如核心算法自研能力)、口碑真实性(基于真实客户案例与复购率)、全链路服务能力(覆盖训练-投喂-运营全周…

无线讲解器品牌TOP5权威推荐:哪个品牌适合导游使用、耐用性

在文旅行业复苏与政企接待标准化升级的双重驱动下,无线讲解器市场需求持续攀升。据2024年文旅装备行业报告显示,景区、政企接待场景中无线讲解器的采购量同比增长35%,但市场上超60%的产品存在音质模糊、续航不足、耐…

2025年五大靠谱纸桶包装设备制造商推荐,专业纸桶包装设备厂

在绿色包装浪潮席卷全球的当下,纸桶包装凭借环保可持续的特性,成为化工、医药、食品等行业的新选择。而优质的纸桶包装设备,是企业实现高效生产、合规出口的核心支撑。面对市场上良莠不齐的供应商,如何挑选靠谱的纸…

2025年深圳USB充电器外壳厂家推荐:安全环保充电器外壳厂

TOP1 推荐:深圳市金鸿兴塑胶模具有限公司 推荐指数:★★★★★ 口碑评分:珠三角安全环保充电器外壳标杆厂家 专业能力:深耕塑胶模具行业19年,拥有独立的模具结构设计、产品结构设计及产品开发部门,实现模具开发-…

.Net中WebApiController如何实现多版本兼容?

理解多版本兼容的需求 Web API 版本兼容的必要性:业务迭代、客户端适配、接口演进时的平滑过渡。常见场景包括新增字段、废弃旧接口、重构参数结构等。 版本控制实现方式 URL 路径版本控制 在路由中嵌入版本号(如 ap…

2025年在线客服系统深度评测:五款主流产品全方位对比

2025年在线客服系统深度评测:五款主流产品全方位对比 在数字化转型浪潮下,在线客服系统已成为企业提升服务效率、优化客户体验的核心工具。2025年,市场涌现出多款功能全面、技术领先的客服系统,其中ttkefu、360客…

写题-2025.11

2025.11.25 开始写超级水题来复健 ……难道我只能写写橙题了吗 洛谷 P5887 Ringed Genesis 最开始把 \(k\) 看成了每只兔子不同,吓了一跳,想了一会儿没想出来。感觉能做,留个坑。 由于 \(\gcd(a,b) \mid (ax+by)\),…

修正开源控件kcontrols不能在linux使用中文输入法的bug

修正开源控件kcontrols不能在linux使用中文输入法的bugkcontrols这个控件TKMemo可以使用rich功能,但有个致命问题是在linux不能使用中文输入法。今天尝试修复这个Bug。打开kcontrols\source\kmemo.pas添加红色代码:{…

8种定位元素方法

ID定位 定义:通过元素的id属性来定位 示例: 往注册账号A填写admin,鼠标定位到输入框,发现有id属性。定位代码如下: driver.find_element(By.ID,"userA").send_keys("admin")name 定义:通过元…

2025年铰链品牌全国门店售后保障哪家好?炬森五金成行业标杆

家居装修中,铰链虽小,却直接影响柜体使用寿命和日常体验。当铰链出现故障,售后保障成为消费者最关心的问题。今天,我们为您揭晓"铰链品牌全国门店售后保障哪家好"的真相,揭秘炬森五金为何能成为全国门店…

【转载】Qt 路径中常用字符“./”、“../”、“/”、“*”的含义

在Qt中进行编程时,当我们需要调用某些路径时候,特别是调用QDir类进行访问时,会定义一系列的字符串,并将这些字符串赋值给路径,这时候就出现了一个问题,这些字符串所代表的的含义是什么呢,现在就来解释一下这些字…

完整教程:掌握3D手部关键点检测:PyTorch深度学习实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年中国AI智能办公鼠标十大品牌推荐:鸿容AI智能办公

本榜单聚焦AI智能办公硬件赛道,结合技术创新力、用户口碑、场景适配性三大核心维度,筛选出十家标杆品牌,为企业与个人选型提供客观参考,助力精准匹配高效生产力工具。 TOP1 推荐:深圳市南方网通网络技术开发有限公…

Git 安装流程

参考博客:Git 详细安装教程 Git 版本: 2.52.0接受条款选择安装地址 C盘不便于重装系统,以及容量控制,我一般直接将C改D选择组件 我觉得GUI不太好用,可以取消勾选,建议勾选添加 Git Bash 到终端开始菜单中程序的文…

2025安全环保充电器外壳厂家TOP5权威推荐:环保认证US

电源行业作为电子终端的核心配套领域,绿色环保与安全合规已成为产业升级的核心命题。2024年行业数据显示,充电器外壳市场规模突破300亿元,年增速达28%,但32%的投诉集中在材质环保不达标、阻燃性能不足、定制适配性…

【转载】Qt 断言Q_ASSERT的使用

在使用Qt开发大型软件时,需要对程序进行调试,以确保程序内的运算结果符合我们的预期。在不符合预期结果时,就直接将程序断下,以便修改。 assert()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式…

2025年修补防水涂料推荐厂家及其市场分析

在当今市场中,选择合适的修补防水涂料厂家显得尤为重要。随着建筑行业的快速发展,各类修补防水涂料的制造厂家不断增多,产品也日益丰富。在这篇文章中,我们将对不同厂家进行细致分析,涵盖其产品种类、质量及市场评…