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;