DbContext AutoDetectChangesEnabled установлен в ложное обнаружение изменений

Я немного озадачен. Из того, что ячитаю настройкуDbContext.AutoDetectChangesEnabled вfalse следует отключить отслеживание изменений, требующих одного звонкаDbContext.DetectChanges для того, чтобы определить изменения, которые будут отправлены в базу данных.

Однако из моих журналов видно, что изменения регистрируются трекером изменений dbContexts, даже если для этого параметра установлено значение false.

Я что-то пропустил?

Версия Entity Framework: 5.0.0.0

Класс DbContext

public class ProjectContext : DbContext {
    public DbSet 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 в Entity Framework Core вы можете найти его подChangeTracker поставленныйConfiguration

Использование как:

context.ChangeTracker.AutoDetectChangesEnabled = false;

//Do something here
context.PriceRecords.Add(newPriceRecord);

context.ChangeTracker.AutoDetectChangesEnabled = true;
 MondKin03 июн. 2019 г., 18:43
Спасибо, именно то, что я искал.

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 методы.

 Ian Warburton03 окт. 2017 г., 12:48
Если вы включите его снова в блоке finally, будет ли он автоматически делать то, что сделал бы, если бы он был включен, но быстрее?
Решение Вопроса

AutoDetectChangesEnabled вfalse Безразлично»Отключить отслеживание изменений. (Тот'с чемAsNoTracking() метод расширения будет делать.) Он просто отключает автоматический вызовDetectChanges что в противном случае произошло бы во многихDbContext Методы API.

НоDetectChanges ISN»t единственный метод, который участвует в отслеживании изменений. Однако, если вы неВызывать его вручную в нужных местах, где это необходимо, отслеживаемые состояния объекта являются неполными или неправильными, что приводит к неправильному сохранению данных.

В твоем случае государствоAdded в первой части вашегоmethod ожидается, даже сAutoDetectChangesEnabled установлен вfalse потому что вы звоните толькоdb.Projects.Add(p), (Между прочим, в вашем коде отсутствует строка, но я думаю, чтоЭто просто ошибка копирования и вставки.) Вызов метода изDbContext API отслеживает изменения правильно, и состояния в трекере будут правильными, если состояние было правильным до вызова.Add

Или другими словами: вызов метода API непревратить правильное состояние в неправильное состояние. Но еслиAutoDetectChangesEnabled являетсяfalse это также выигралоповернуть неправильное состояние в правильное состояние, которое будет иметь место, еслиAutoDetectChangesEnabled является .true

Тем не менее, во второй части вашегоmethod вы просто меняете значение свойства POCO. После этой точки состояние трекера изменения неверно (Unchanged) и без звонкаDetectChanges (вручную или - еслиAutoDetectChangesEnabled являетсяtrue - автоматически вChangeTracker.Entries или жеSaveChanges) это никогда не будет налажено. В результате измененное значение свойства не сохраняется в базе данных.

В последнем разделе упоминается состояние яUnchangedЯ ссылаюсь на свой собственный тест (а также на то, что я ожидаю). Я нене знаю и не могут воспроизвести, почему у вас есть состояние.Modified

Извините, если это звучит немного запутанно.Артур Виккерс может объяснить это лучше.

Я нахожу автоматическое обнаружение изменений и поведение при отключении довольно сложным для понимания и освоения, и я обычно нене трогать по умолчанию (=AutoDetectChangesEnabledtrue) для любых отслеживаемых изменений, которые являются более сложными, чем самые простые вещи (например, массовое добавление объектов в цикле и т. д.).

 Ed S.12 окт. 2013 г., 19:55
Ах, прости, я неправильно понял это предложение.
 Jesse31 мая 2013 г., 23:39
Я должен был прочитать это несколько раз, но это действительно помогает ответить на мой вопрос, спасибо! Извините за ошибку при копировании и вставке; я'Обновлю вопрос для потомков.
 Slauma12 окт. 2013 г., 03:12
@EdS .: Массовое добавление является одним изсамые простые вещи Я имел в виду, где я на самом делебыло бы отключить автоматическое обнаружение изменений.
 Iman Mahmoudinasab06 янв. 2014 г., 08:49
Может быть, полезная ссылка:Entity Framework Automatic Detect Changes
 Sana03 июн. 2019 г., 13:53
Как издеваться над этим?
 Ed S.11 окт. 2013 г., 23:14
К несчастью, "массовое добавление сущностей в цикл " когда вы хотите, чтобы отслеживание изменений было отключено. Этомассивный Ускорение (размер выборки 1, протестировано в моем приложении, но это была единственная разница между двумя прогонами с добавлением ~ 3000 строк).

Ваш ответ на вопрос