EF 4.1, POCO: я выключил AutoDetectChanges ( Configuration.AutoDetectChangesEnabled = false ) для ускорения обновления данных.Затем я запускаю Добавить или Присоединить с измененным состоянием сущности на EntityState.Modified .Все это приводит к тому, что ссылки на другие объекты не обновляются в базе данных.Однако все скалярные свойства успешно обновлены.
Показанный профилировщик EF генерирует операцию обновления SQL для каждого скалярного свойства, но не для ссылочного типа, хотя я действительно изменил его значение в своем коде.Эта проблема воспроизводится для каждого типа объектов в моей модели.
Операция добавления или Присоединение с EntityState.Added , оба работают нормально.Если я включу AutoDetectChanges , все будет работать нормально, как и ожидалось, для обновленных записей.
Помогите, пожалуйста, выяснить, в чем дело.Я не могу найти хорошую исчерпывающую документацию по обнаружению изменений EF.
ОБНОВЛЕНИЕ
Меня попросили привести пример кода для воспроизведения проблемы.Домен:
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public virtual string City { get; set; }
}
DataContext:
public class DataContext : DbContext
{
public DbSet<Client> Clients { get; set; }
public DbSet<Address> Address { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Client>().HasOptional(c => c.Address);
}
}
Добавить одну запись в таблицу Клинта и одну в адрес.Укажите клиента на адрес.Затем запустите следующий код:
using (var cntx = new DataContext())
{
cntx.Configuration.AutoDetectChangesEnabled = false; // Reason of problem
var client = cntx.Clients.First();
client.Name = "Anna"; // This property will be updated
client.Address = null; // This property will not be updated
cntx.Clients.Attach(client);
cntx.Entry(client).State = EntityState.Modified;
cntx.SaveChanges();
}
Этот код генерирует скрипт SQL следующим образом:
update [dbo].[Clients] set [Name] = 'Anna'
where ([Id] = 1)
Установите для AutoDetectChangesEnabled значение true и снова запустите код, на этот раз все в порядке:
update [dbo].[Clients]
set [Name] = 'Anna', [Address_Id] = null
where (([Id] = 1) and [Address_Id]=1)
Обратите внимание, что не имеет значения, если вы измените значение адреса с определенного значения на нулевое, или обратно на конкретное значение, или с одного конкретного значения на другое конкретное значение, любое изменение не отслеживается, пока AutoDetectChanges = false.Похоже, ошибка EF.