c#中Change Tracker

Change Tracker 通过记录实体的状态来跟踪对象的变化。当你对一个实体(如一个 User 对象)进行修改时,Entity Framework 会跟踪该实体的状态,直到调用 SaveChanges() 时才将这些更改同步到数据库。

Entity Framework 中的实体有以下几种可能的状态,Change Tracker 负责管理这些状态:

  1. Added(新增):实体是新创建的,并且还没有保存到数据库中。

    • 例如,在 context.Users.Add(new User()) 后,User 实体的状态会是 Added
  2. Modified(修改):实体已经存在于数据库中,并且其属性值被修改过。

    • 例如,user.Name = "new name" 后,user 实体的状态会是 Modified
  3. Deleted(删除):实体被标记为删除,表示要从数据库中移除。

    • 例如,context.Users.Remove(user) 后,user 实体的状态会是 Deleted
  4. Unchanged(未变更):实体没有做任何修改,它的值与数据库中的记录相同。

    • 例如,在查询数据库并没有修改实体后,实体状态会是 Unchanged
  5. Detached(分离):实体不再与任何 DbContext 实例相关联。它不参与 Change Tracker 的跟踪。

    • 例如,实体从上下文中移除(context.Entry(user).State = EntityState.Detached)或不在上下文管理的情况下。

// 检查用户的当前状态

var entry = context.Entry(user);

Console.WriteLine(entry.State); // 输出: Modified

Change Tracker 底层架构

  1. DbContext:

    • DbContext 是 Entity Framework 与数据库交互的主要类。

    • 它包含一个 ChangeTracker 属性,该属性可以用于访问和操作跟踪的实体。

  2. ChangeTracker:

    • ChangeTracker 是一个内部对象,负责管理实体的状态(如新增、修改、删除和未更改的状态)。

    • 它通过跟踪 DbContext 中的实体的状态来进行工作。

  3. DbEntityEntry:

    • DbEntityEntry 是用于访问单个实体状态的核心类。它提供了方法来获取和设置实体的状态,管理实体的属性值,甚至可以进行深度比较(例如,检测修改的字段)。

底层工作原理

ChangeTracker 会在 DbContext 中维护一组被跟踪的实体及其状态。它会根据实体的状态(例如,AddedModifiedDeleted 等)来确定数据库操作的类型,并生成相应的 SQL 操作。在执行 SaveChanges() 时,ChangeTracker 会识别这些变化并生成相应的 SQL 语句。

ChangeTracker 和 DbContext

DbContext 在内存中维护了一个包含所有跟踪实体的列表。这些实体会被 ChangeTracker 追踪,当你对实体执行操作时(如增加、修改或删除),ChangeTracker 会记录它们的状态。

  • 当一个实体被添加到 DbContext 中时,它的状态会被标记为 Added

  • 如果实体的属性发生变化,ChangeTracker 会将其状态标记为 Modified

  • 如果你调用 Remove() 删除一个实体,它的状态将被标记为 Deleted

DbContext 和 Entity Entry

当你通过 DbContext.Entry(entity) 访问实体时,实际上是获取了该实体的 DbEntityEntry 对象。DbEntityEntry 提供了对实体的状态、属性值和其他元数据的访问。

简化实现

// 自定义的数据库上下文类,模拟了 Entity Framework 的行为
public class MyOwnDatabase
{// 用于存储被跟踪的实体的列表public List<EntityEntry> TrackedEntities { get; } = new List<EntityEntry>();// 向数据库添加一个实体(模拟 Entity Framework 中的 Add 方法)public void Add(object entity){// 创建一个新的 EntityEntry 实例,表示该实体的状态为 "Added"(新增)var entry = new EntityEntry(entity, EntityState.Added);// 将该实体的 Entry 添加到 TrackedEntities 列表中进行跟踪TrackedEntities.Add(entry);}// 从数据库删除一个实体(模拟 Entity Framework 中的 Remove 方法)public void Remove(object entity){// 创建一个新的 EntityEntry 实例,表示该实体的状态为 "Deleted"(删除)var entry = new EntityEntry(entity, EntityState.Deleted);// 将该实体的 Entry 添加到 TrackedEntities 列表中进行跟踪TrackedEntities.Add(entry);}// 获取一个实体的 Entry,用于查看或修改实体的状态public EntityEntry Entry(object entity){// 返回 TrackedEntities 中的匹配实体 Entry(如果有的话)return TrackedEntities.FirstOrDefault(e => e.Entity == entity);}// 保存更改到数据库(模拟 Entity Framework 中的 SaveChanges 方法)public void SaveChanges(){// 遍历所有被跟踪的实体,执行相应的数据库操作foreach (var entry in TrackedEntities){switch (entry.State){case EntityState.Added:   // 新增状态:执行插入操作Insert(entry);break;case EntityState.Modified: // 修改状态:执行更新操作Update(entry);break;case EntityState.Deleted: // 删除状态:执行删除操作Delete(entry);break;}}}// 执行插入操作,模拟 INSERT SQL 语句的执行private void Insert(EntityEntry entry){// 输出模拟插入操作的消息Console.WriteLine($"Executing INSERT for {entry.Entity.GetType().Name}");}// 执行更新操作,模拟 UPDATE SQL 语句的执行private void Update(EntityEntry entry){// 输出模拟更新操作的消息Console.WriteLine($"Executing UPDATE for {entry.Entity.GetType().Name}");}// 执行删除操作,模拟 DELETE SQL 语句的执行private void Delete(EntityEntry entry){// 输出模拟删除操作的消息Console.WriteLine($"Executing DELETE for {entry.Entity.GetType().Name}");}
}// 表示被跟踪的实体及其状态的类
public class EntityEntry
{// 被跟踪的实体public object Entity { get; }// 实体的当前状态(新增、修改、删除、未更改)public EntityState State { get; set; }// 构造函数,接受实体和其状态作为参数public EntityEntry(object entity, EntityState state){Entity = entity;   // 设置实体State = state;     // 设置实体的状态}
}// 定义实体的状态枚举
public enum EntityState
{Added,    // 实体已添加(新增)Modified, // 实体已修改Deleted,  // 实体已删除Unchanged // 实体未发生变化
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux安装BellSoft JDK 17 LTS

原来使用的OpenJdk&#xff0c;看到SpringBoot官网推荐&#xff08;如下图&#xff09;贝尔实验室的JDK&#xff0c;打算换一下 官方下载链接 JKD下载 可以看到Win、Mac、Linux都提供了&#xff0c;并且还有x86架构和arm架构的 在Linux中我们可以使用 uname -a 查看当前操作系…

C++(九)

前言&#xff1a; 本文主要讲述运算符的优先顺序。 一&#xff0c;运算符的优先级。 请看以下表达式&#xff1a; a32*5 运算结果为&#xff1a;13. 可以看到&#xff0c;在此代码中&#xff0c;先运行了2*5的结果&#xff0c;在此基础上在进行3操作&#xff0c;因此结果…

学生公寓智能限电系统的功能和作用

学生公寓智能限电系统‌是一种用于管理和限制学生公寓用电的设备和技术&#xff0c;旨在确保用电安全、防止火灾事故&#xff0c;并促进节能减排。以下是关于学生公寓智能限电系统的详细介绍&#xff1a; 1、功能和作用 智能限电系统通过以下功能来管理和限制用电&#xff1a…

嵌入式入门Day25

数据结构Day 6,IO Day1 查找算法顺序查找折半查找&#xff08;二分查找&#xff09;哈希查找 IO概念标准IO创建递归索引&#xff08;用于查询结构体定义&#xff09; 文件IO标准IO缓冲区指针相关函数 查找算法 顺序查找 关键字&#xff1a;分为主关键字和次关键字主关键字&am…

内网代理转发工具

概念区分 端口转发 端口转发就是将一个端口&#xff0c;这个端口可以本机的端口也可以是本机可以访问到的任意主机的端口&#xff0c;转发到任意一台可以访问到的IP上&#xff0c;通常这个IP是公网IP。 适用端口转发的网络环境有以下几种&#xff1a; 服务器处于内网&#x…

MNIST_FC

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

掌握时间,从`datetime`开始

文章目录 掌握时间&#xff0c;从datetime开始第一部分&#xff1a;背景介绍第二部分&#xff1a;datetime库是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 获取当前日期和时间2. 创建特定的日期3. 计算两个日期…

算法之括号匹配中最长有效字符串

目录 1. 题目2. 解释3. 思路4. 代码5. 总结 1. 题目 任何一个左括号都能找到和其正确配对的右括号任何一个右括号都能找到和其正确配对的左括号 求最长的有效的括号长度 2. 解释 例如&#xff0c;这里的括号 ((((()()()()()()()))()最长有效是&#xff1a;((()()()()()()(…

统信桌面专业版部署postgresql-14.2+postgis-3.2方法介绍

文章来源&#xff1a;统信桌面专业版部署postgresql-14.2postgis-3.2方法介绍 | 统信软件-知识分享平台 应用场景 CPU架构&#xff1a;X86&#xff08;海光C86-3G 3350&#xff09; OS版本信息&#xff1a;1070桌面专业版 软件信息&#xff1a;postgresql-14.2postgis-3.2 …

【书生大模型实战营】Python 基础知识-L0G2000

前言&#xff1a;本文是书生大模型实战营系列的第2篇文章&#xff0c;是入门岛的第二个任务&#xff0c;主题为&#xff1a;Python基础知识。 官方教程参考链接&#xff1a;Tutorial/docs/L0/Python at camp4 InternLM/Tutorial 1.任务概览 本关为Python基础关卡&#xff0…

智能安全新时代:大语言模型与智能体在网络安全中的革命性应用

一、引言 随着信息技术的飞速发展&#xff0c;网络安全问题日益严重&#xff0c;成为各行各业面临的重大挑战。传统的安全防护措施已难以应对日益复杂的网络威胁&#xff0c;人工智能&#xff08;AI&#xff09;技术的引入为网络安全带来了新的希望。特别是大语言模型&#xff…

数仓技术hive与oracle对比(三)

更新处理 oracle使用dblink透明网关连接其他数据库&#xff0c;mysql、sqlserver、oracle&#xff0c;然后用sql、plsql更新数据&#xff1b;或者使用etl工具实现更新。 hive使用sqoop连接mysql、sqlserver、oracle实现数据更新。 oracle oracle数据加载命令 批量sql脚本上…

在 Vue.js 中使用对象映射和枚举类型

学习啦&#xff01; 对象映射是一种将一个对象的属性名映射到另一个对象的属性名的方法。 const keyMapping {username: 用户名, gender: { label: 性别, mapping: gender }, // gender 映射为 性别email: 邮箱, // email 映射为 邮箱phone: 电话, // phone 映射为 电话addres…

嵌入式学习(15)-stm32通用GPIO模拟串口发送数据

一、概述 在项目开发中可能会遇到串口不够用的情况这时候可以用通过GPIO来模拟串口的通信方式。 二、协议格式 按照1位起始位8位数据位1位停止位的方式去编写发送端的程序。起始位拉低一个波特率的时间&#xff1b;发送8位数据&#xff1b;拉高一个波特率的时间。 三、代码 …

【C语言期末复习全攻略】:知识点汇总与考试重点剖析、附刷题资料软件

零、引用 期末考试临近&#xff0c;无论你是初学者还是“熬夜选手”&#xff0c;C语言的学习都需要系统梳理和重点突破。本文将全面总结C语言的核心知识点&#xff0c;并针对考试中常见的题型提供复习建议&#xff0c;助你轻松拿下高分。 文末提供了一款免费的C语言刷题软件 …

美颜SDK接入实战:构建智能化直播美颜APP的技术路径详解

如何将美颜SDK顺利接入并构建一个智能化的直播美颜APP呢&#xff1f;本文将从技术路径的角度&#xff0c;带你深入解析这一过程。 一、了解美颜SDK的基本功能 美颜SDK通常包括多个功能模块&#xff0c;针对不同的直播场景&#xff0c;SDK会提供针对性的优化算法&#xff0c;确…

【Spring】Spring事务和事务传播机制

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【Java】登神长阶 史诗般的Java成神之路 一、Spring事务 我们在MySQL阶段已经学习了MySQL的事务相关知识&#xff0c;详情可见 【MySQL数据库】索引与事务-CSDN博客 1、概念 我们在此做一个简单回顾…

Qt 小项目 学生管理信息系统

主要是对数据库的增删查改的操作 登录/注册界面&#xff1a; 主页面&#xff1a; 添加信息&#xff1a; 删除信息&#xff1a; 删除第一行&#xff08;支持多行删除&#xff09; 需求分析&#xff1a; 用QT实现一个学生管理信息系统&#xff0c;数据库为MySQL 要求&#xf…

核心网S6730-H48X6C-V2堆叠

核心网是电信网络的中枢,负责数据传输、服务提供和网络管理,对保障通信质量、支持新技术服务和维护网络安全至关重要。堆叠技术通过将多个网络设备逻辑上整合为一个单元,简化管理,提升网络可用性和性能,同时降低成本,增强网络扩展性。 堆叠在网络建设中至关重要,它通过…

教程: 5分钟部署 APIPark 开源 LLM Gateway 与 API 开放门户

极大简化了大语言模型调用的过程&#xff0c;无需复杂代码即可同时连接主流大语言模型&#xff0c;让企业更加快捷、安全地使用AI。喜欢或感兴趣的小伙伴们赶紧去体验吧&#xff01; &#x1f517;更详细使用教程可以查看&#xff1a;APIPark 产品使用文档 APIPark 提供出色的…