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

EF Core 深入学习

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.zskr.cn/news/62672.html

相关文章:

  • 2025年五大靠谱纸桶包装设备制造商推荐,专业纸桶包装设备厂
  • 2025年深圳USB充电器外壳厂家推荐:安全环保充电器外壳厂
  • .Net中WebApiController如何实现多版本兼容?
  • 写题-2025.11
  • Git 安装流程
  • 2025年襄阳地区十大包装盒定制企业推荐:知名的包装盒机构有
  • 2025年深圳东莞惠州塑胶外壳定制公司推荐:安全环保的塑胶外
  • 八数码难题
  • 【转载】Qt QCustomPlot 使用教程
  • 2025年11月营销智能体选择指南:权威榜单与用户评价深度分析
  • 2025年11月营销智能体推荐榜单:五大主流平台深度对比与选择指南
  • 八皇后
  • 机器学习如何优化MRI扫描速度与质量
  • linux系统下独立声卡继电器总是自动反复吸合
  • 2025年3200度石墨化炉、卧式石墨化炉、碳纤维石墨化炉品
  • 2025年11月GPU服务器公司评价榜:技术实力与服务能力全面分析
  • 2025年全国十大西点烘焙培训学校排行榜,优美西点口碑怎么样
  • 2025年可靠的涤纶三明治网布/防霉抗菌三明治网布最新TOP品牌厂家排行
  • PyTorch:AI时代的深度学习利器 - 实践
  • 2025年优秀的方便面生产线/大型方便面生产线厂家最新推荐权威榜
  • 2025年正规的组合式空调机组厂家最新热销排行
  • 完整教程:MCP服务器日志轮转:Awesome Claude Code磁盘管理终极指南
  • 2025年口碑好的烧烤年糕机热门厂家推荐榜单
  • 2025年中国益生菌厂家推荐:益生菌厂商及益生菌环保工厂十大
  • ? #7
  • 2025年评价高的钢结构维护材料销售厂家实力及用户口碑排行榜
  • 2025年11月AI智能客服机器人品牌排行榜出炉:聚焦AI交互能力与政企服务技术路线
  • HtmlWebpackPlugin类完全解读:API参数与方法详解 - 指南
  • 2025年11月AI智能客服机器人品牌排行榜出炉:聚焦语音交互能力与场景适配技术路线
  • 2025年比较好的304不锈钢网片品牌厂家排行榜