我有点难住了。根据我读到的设置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
否则会发生在许多DbContext
API 方法。
But DetectChanges
不是参与变更跟踪的唯一方法。但是,如果您没有在需要的正确位置手动调用它,则跟踪的实体状态不完整或错误,导致数据保存不正确。
在你的情况下,国家Added
在你的第一部分method
预计,即使AutoDetectChangesEnabled
set to false
因为你只打电话db.Projects.Add(p)
。 (顺便说一句,您的代码中缺少该行,但我猜这只是复制和粘贴错误。)DbContext
API 正确跟踪更改,如果在调用之前状态正确,则跟踪器中的状态将是正确的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(使用前将#替换为@)