DbContext AutoDetectChangesEnabled 设置为 false 检测更改

2024-03-29

我有点难住了。根据我读到的设置DbContext.AutoDetectChangesEnabled to false应该禁用需要调用的更改跟踪DbContext.DetectChanges为了识别要发送到数据库的更改。

但是,从下面的日志可以清楚地看出,即使设置设置为 false,dbContexts 更改跟踪器也会注册更改。

我错过了什么吗?

实体框架版本:5.0.0.0

DbContext 类

public class ProjectContext : DbContext {
    public DbSet<Project> Projects {get;set;}
}

控制器类

private ProjectContext db = new ProjectContext();

public method(){
    Project p = new Project("uniqueName");
    db.Configuration.AutoDetectChangesEnabled = false;
    db.Projects.Add(p);
    DebugChangeTracker();
    db.SaveChanges();

    db.Projects.First().ProjectName = "a differentName!";
    DebugChangeTracker();
    db.SaveChanges();
}

记录方式

    private void DebugChangeTracker()
    {
        var path = "C:\\mypath\\";
        path = path + Util.GetMsSinceEpoch().ToString() + "changeTracker.log";

        using (StreamWriter sw = new StreamWriter(path))
        {
            var changeTracker = db.ChangeTracker;
            var entries = changeTracker.Entries();
            foreach (var x in entries)
            {

                var name = x.Entity.ToString();
                var state = x.State;

                sw.WriteLine("");
                sw.WriteLine("***Entity Name: " + name +
                             "is in a state of " + state);
                var currentValues = x.CurrentValues;
                sw.WriteLine("***CurrentValues***");
                PrintPropertyValues(currentValues,sw);
                if (state != EntityState.Added)
                {
                    sw.WriteLine("***Original Values***");
                    PrintPropertyValues(x.OriginalValues,sw);
                }
            }
        }
    }

第一个日志

***Entity Name: Models.Projectis in a state of Added
***CurrentValues***
ProjectId:0
ProjectName:uniqueName

第二条日志

***Entity Name: Models.Projectis in a state of Modified
***CurrentValues***
ProjectId:1
ProjectName:uniqueName
***Original Values***
ProjectId:1
ProjectName:a differentName!

Setting AutoDetectChangesEnabled to false不禁用更改跟踪。 (这就是AsNoTracking()扩展方法就可以了。)它只是禁用自动调用DetectChanges否则会发生在许多DbContextAPI 方法。

But DetectChanges不是参与变更跟踪的唯一方法。但是,如果您没有在需要的正确位置手动调用它,则跟踪的实体状态不完整或错误,导致数据保存不正确。

在你的情况下,国家Added在你的第一部分method预计,即使AutoDetectChangesEnabled set to false因为你只打电话db.Projects.Add(p)。 (顺便说一句,您的代码中缺少该行,但我猜这只是复制和粘贴错误。)DbContextAPI 正确跟踪更改,如果在调用之前状态正确,则跟踪器中的状态将是正确的Add.

或者换句话说:调用 API 方法不会将正确状态转变为错误状态。但是:如果AutoDetectChangesEnabled is false它也不会将错误的状态变成正确的状态,如果AutoDetectChangesEnabled is true.

然而,在你的第二部分method您只是更改 POCO 属性值。在此之后,更改跟踪器状态是错误的(Unchanged)并且无需致电DetectChanges(手动或 - 如果AutoDetectChangesEnabled is true- 自动进入ChangeTracker.Entries or SaveChanges)它永远不会被调整。效果是更改的属性值不会保存到数据库中。

在最后一节提到状态Unchanged我指的是我自己的测试(也是我所期望的)。我不知道也无法重现为什么你有状态Modified.

抱歉,如果这听起来有点令人困惑。阿瑟·维克斯可以更好地解释这一点。 http://blog.oneunicorn.com/2012/03/12/secrets-of-detectchanges-part-3-switching-off-automatic-detectchanges/

我发现自动更改检测和禁用它时的行为相当难以理解和掌握,而且我通常不会触及默认值(AutoDetectChangesEnabled = true)用于比最简单的事情更复杂的任何跟踪更改(例如在循环中批量添加实体等)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DbContext AutoDetectChangesEnabled 设置为 false 检测更改 的相关文章

随机推荐

  • 访问 tf.keras.callbacks.Callback 中已弃用的属性“validation_data”

    我决定从 keras 切换到 tf keras 按照推荐here https www pyimagesearch com 2019 10 21 keras vs tf keras whats the difference in tensor
  • “heroku run rake asset:clean” 不会清理任何东西

    我执行 heroku run rake assets clean Running rake assets clean attached to terminal up run 2 usr local bin ruby app vendor b
  • Git commit hook - 如何使用 commit-msg 挂钩检查消息中的字符串?

    我需要创建一个 commit msg 挂钩来检查提交消息的任何部分是否包含 app asana 我搜索了一些参考资料和文档 我知道我需要为此使用 commit msg 我必须使用 Perl 或 Bash 来完成此操作 有人对此有线索吗 或者
  • 使用 JQ 解析 JSON 行以按顺序翻转键值

    我有一个包含 json 行的文件 需要根据每个 json 的抖动 alert status 值的序列来验证其有效性 有效 json 行的示例 id 123 code foo severity Critical severityCode 1
  • Python 2 和 3 中的字符串到字节

    我的函数需要将输入作为字符串或二进制数据 例如 从文件中读取 如果它是一个字符串 我想将其转换为原始数据 bytes or bytearray 在Python 3中 我可以做data bytes data utf8 然而 这在 Python
  • AWS lambda 和数据库[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我一直在理论上了解到 创建与数据库的新连接是昂贵的操作 因此 我们应该保持打开的连接池并将其用于数据库操作 在考虑 AWS lambda 时 假
  • 如何将 JSON 响应包装在父对象中

    我的 Spring REST 服务的当前响应如下 id 5cc81d256aaed62f8e6462f4 email email protected cdn cgi l email protection id 5cc81d386aaed62
  • Android 上的 Youtube API 播放器每 2 秒自动暂停一次

    我正在制作一个使用 YouTube API 来播放 YouTube 视频的应用程序 当我进入全屏模式时 我将播放器样式切换为 CHROMELESS 因为我想创建自己的媒体控件集 我开发了一套手势来映射音量 亮度和搜索的变化 当这些变化发生时
  • Cakephp REST API 消除了 .format 的必要性

    我正在努力创建一个仅获取和返回 JSON 数据的 REST api 我正在遵循蛋糕指南 我的默认路线是这样的 GET recipes format GET recipes 123 format POST recipes format PUT
  • MongoDB 按数组中的元素进行分组

    我有一个看起来像这样的集合 id id1 tags a b id id2 tags b c id id3 tags a c 如何进行按 tags 数组中的每个元素进行分组的查询 以便结果如下所示 a 2 b 2 c 2 其中2是它出现的次数
  • 未使用的功能会改变性能

    在尝试估计之间的性能差异时push back and std inserter我遇到了一个非常奇怪的性能问题 让我们考虑以下代码 include
  • 是否可以使用 AWS PHP SDK 将子域添加到 Route53?

    我正在开发一个项目 我们将在 Route53 中创建子域和域 我们希望有一种方法可以通过编程来完成此操作 PHP 文档的 SDK 似乎有点简单 但看起来 createHostedZone 可用于创建域或子域记录 changeResource
  • C#:捕获另一个应用程序的窗口状态更改(我认为是用 c/c++ 编写的)

    我遇到一种情况 我需要捕获另一个窗口的窗口状态更改 该窗口不属于我的应用程序 并且不是我编写的 我认为它是用 C 编写的 实际上我正在使用一个单独的线程 我不断地执行 GetWindowState 并在该值更改时触发自定义事件 我有窗口的句
  • 获取行中日期值之前的最新日期

    我正在使用 MSSQL 2008 R2 我正在尝试获取最新数据日期到存储在另一列中的日期 我可以在子查询中使用 max ProcedureDate 提取最新的数据日期 但是 我需要列中存储的日期之前的最新日期 这是一个例子 Current
  • 如何设置任务的计划完成日期?

    我试图弄清楚如何在创建或更新任务时设置计划完成日期 任务的计划完成日期始终等于项目创建的日期 我使用了几种不同的日期时间格式 但它从未改变 这是我使用过的两个没有抛出错误的 2015 05 02T08 00 00 000 0500 2015
  • 可以打印超过 100 行的 data.table 吗?

    data table 有一个很好的功能 可以抑制输出到表的头部和尾部 是否可以一次查看 打印 100 行以上 library data table Convert the ubiquitous iris data to a data tab
  • 实体框架代码优先和连接字符串

    我有一个使用 Entity Framework Code First 的小型 MVC 3 应用程序 并为模型使用此连接字符串 data source SQLEXPRESS Integrated Security SSPI AttachDBF
  • Flask 应用程序中的 Rpy2:致命错误:无法初始化 JIT

    我有一个 Flask 应用程序 我正在尝试添加一个 RESTful 端点 该端点使用 rpy2 从 rds文件 当我运行我的测试脚本时python3 testscript py其中包含import rpy2 robjects as obje
  • Laravel where if 语句

    我在从数据库中选择时遇到了问题 基本上我想要实现的是 我有一个包含 3 列的表 type number date 我需要根据列 类型 执行操作 If type 1 then where number gt 1 else where date
  • DbContext AutoDetectChangesEnabled 设置为 false 检测更改

    我有点难住了 根据我读到的设置DbContext AutoDetectChangesEnabled to false应该禁用需要调用的更改跟踪DbContext DetectChanges为了识别要发送到数据库的更改 但是 从下面的日志可以