gpt4 book ai didi

entity-framework - DbContext AutoDetectChangesEnabled 设置为 false 检测更改

转载 作者:行者123 更新时间:2023-12-03 06:22:50 25 4
gpt4 key购买 nike

我有点困惑。根据我的阅读,将 DbContext.AutoDetectChangesEnabled 设置为 false 应该禁用更改跟踪,需要调用 DbContext.DetectChanges 才能识别更改发送到数据库。

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

我错过了什么吗?

Entity Framework 版本:5.0.0.0

DbContext 类

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

Controller 类

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!

最佳答案

AutoDetectChangesEnabled 设置为 false 不会禁用更改跟踪。 (这就是 AsNoTracking() 扩展方法的作用。)它只是禁用 DetectChanges 的自动调用,否则许多 DbContext API 中会发生这种情况方法。

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

在您的情况下,方法第一部分中的状态已添加是预期的,即使AutoDetectChangesEnabled设置为false 因为您只调用 db.Projects.Add(p)。 (顺便说一句,您的代码中缺少该行,但我猜这只是复制和粘贴错误。)从 DbContext API 调用方法可以正确跟踪更改,并且如果跟踪器中的状态正确,则跟踪器中的状态将是正确的在调用 Add 之前状态是正确的。

或者换句话说:调用 API 方法不会将正确状态转变为错误状态。但是:如果 AutoDetectChangesEnabledfalse,它也不会将错误状态转换为正确状态,而如果 AutoDetectChangesEnabled 则会出现这种情况>true.

但是,在方法的第二部分中,您只是更改 POCO 属性值。此后,更改跟踪器状态错误 (Unchanged),并且未调用 DetectChanges(手动或 - 如果 AutoDetectChangesEnabledtrue - 自动在 ChangeTracker.EntriesSaveChanges 中)它永远不会被调整。效果是更改的属性值不会保存到数据库中。

在最后一节提到状态未更改时,我指的是我自己的测试(以及我所期望的)。我不知道也无法重现为什么您的状态为Modified

抱歉,如果这听起来有点令人困惑。 Arthur Vickers can explain it better.

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

关于entity-framework - DbContext AutoDetectChangesEnabled 设置为 false 检测更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16863382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com