DbContext AutoDetectChangesEnabled значение false обнаружение изменений
Я немного в тупик. Из того, что я прочитал, установка DbContext.AutoDetectChangesEnabled to false должен отключить отслеживание изменений, требующее вызова DbContext.DetectChanges для идентификации изменений, которые будут отправлены в базу данных.
однако из моих журналов ниже ясно, что изменения регистрируются dbcontexts change tracker, даже с настройкой false.
Я что-то пропустила?
Entity Framework Версия: 5.0.0.0
DbContext можно класс!--9-->
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!
3 ответов
задание AutoDetectChangesEnabled до false не отключает отслеживание изменений. (Вот что такое AsNoTracking() метод расширения будет делать.) Он просто отключает автоматический вызов DetectChanges что в противном случае произошло бы во многих DbContext методы API.
но DetectChanges не единственный метод, который участвует в отслеживании изменений. Однако, если вы не вызываете его вручную в нужных местах, где это необходимо, отслеживаемые состояния сущности являются неполными или неправильными, что приводит к неправильному сохранению данные.
в вашем случае государство Added в первой части вашего method ожидается, даже с AutoDetectChangesEnabled значение false потому что вы только называете db.Projects.Add(p). (Строка отсутствует в вашем коде кстати, но я думаю, что это просто ошибка копирования и вставки.) Вызов метода из DbContext API отслеживает изменения правильно, и состояния в трекере будут правильными, если состояние было правильным до вызова Add.
или другими словами: вызов метода API не превращает правильное состояние в неправильное состояние. Но: Если AutoDetectChangesEnabled is false это также не превратит неправильное состояние в правильное состояние, которое было бы в случае, если AutoDetectChangesEnabled is true.
однако, во второй части вашего method вы просто меняете значение свойства POCO. После этого момента состояние отслеживания изменений неверно (Unchanged) и без звонка DetectChanges (вручную или-if AutoDetectChangesEnabled is true - автоматически ChangeTracker.Entries или SaveChanges) он никогда не будет отрегулирован. В результате получается, что измененное значение свойства не сохраняется в базе данных.
в последнем разделе упоминается государство Unchanged я ссылаюсь на свой собственный тест (а также то, что я ожидал). Я не знаю и не могу воспроизвести, почему у вас государство Modified.
Извините, если это звучит немного запутанным. Артур Викерс может объяснить это лучше.
я нахожу автоматическое обнаружение изменения и поведение при отключении его довольно трудно понять и Мастер и я обычно не касаемся значения по умолчанию (AutoDetectChangesEnabled = true) для любых отслеживаемых изменений, которые сложнее, чем самые простые вещи (например, массовое добавление объектов в цикл и т. д.).
по лицу Framework автоматическое обнаружение изменений в статье
они сказали:
вы можете получить значительные производительность поворотом выкл на
some cases
посмотрите на этот пример из той статьи
using (var context = new BloggingContext())
{
try
{
context.Configuration.AutoDetectChangesEnabled = false;
// Make many calls in a loop
foreach (var blog in aLotOfBlogs)
{
context.Blogs.Add(blog);
}
}
finally
{
context.Configuration.AutoDetectChangesEnabled = true;
}
}
этот код позволяет избежать ненужных вызовов DetectChanges это произошло бы при вызове DbSet.Add и SaveChanges методы.
если кто-то ищет AutoDetectChangesEnabled в Entity Framework Core вы можете найти его в разделе ChangeTracker insted Configuration
использование как:
context.ChangeTracker.AutoDetectChangesEnabled = false;
//Do something here
context.PriceRecords.Add(newPriceRecord);
context.ChangeTracker.AutoDetectChangesEnabled = true;