Игнорировать нулевые значения исправьте ядро ef

#c# #entity-framework #.net-core

Вопрос:

Обновление записей с помощью EF, но оно не обновляется соответствующим образом. Я просто хочу обновить только те поля, которые не являются пустыми и измененными. В предыдущем я делал так:

 _context.Attach(exist).CurrentValues.SetValues(t);  

который обновит все поля, а я этого не хочу.

Есть ли что-нибудь, что я пропустил в своем коде?

 public virtual async Tasklt;Tgt; UpdateAsync(T t, object key)  {  if (t == null)  return null;    T exist = await _context.Setlt;Tgt;().FindAsync(key);   if (exist != null)  {   // _context.Attach(exist).CurrentValues.SetValues(t);   _context.Attach(exist);    var entry = _context.Entry(t);   Type type = typeof(T);  PropertyInfo[] properties = type.GetProperties();   foreach (PropertyInfo property in properties)  {  if (property.GetValue(t, null) == null)  {  entry.Property(property.Name).IsModified = false;  }  }   // _context.Attach(exist).CurrentValues.SetValues(t);   await _context.SaveChangesAsync();  }   return exist;  }  

Комментарии:

1. В чем смысл этого кода? Вам ничего из этого не нужно для обновления объекта. Загрузите объекты, измените их свойства, вызовите SaveChangesAsync , чтобы сохранить все изменения сразу. DbContext уже является универсальной единицей работы с несколькими объектами. DbSet уже является универсальным репозиторием. Изменения уже отслеживаются. И это .Setlt;Tgt;() может вызвать проблемы с производительностью в более старых версиях ядра EF — DbContext будет кэшировать метаданные для всех определенных свойств набора баз данных. Только в EF Core 5 (или 6?) Setlt;Tgt;() также добавлено кэширование

2. In previous I'm doing like this: _context.Attach(exist).CurrentValues.SetValues(t); зачем и это делать? Если вы изменяете объект, загруженный самим ядром EF, вам это не нужно Attach . Объект уже прикреплен и отслежен. Вам нужно использовать только Attach для сохранения отдельного объекта, например, отправленного на сервер с помощью PUT. Если вы хотите изменить только измененные свойства, вам нужно найти, что это такое. Один из способов-использовать PATCH вместо PUT и отправлять измененные свойства только вашему контроллеру. В противном случае вам придется фактически загрузить объект и проверить наличие изменений

Ответ №1:

Я использую что-то вроде этого

 public virtual async Tasklt;Tgt; UpdateAsync(T t, object key) {  if (t == null)  return null;    T exist = await _context.Setlt;Tgt;().FindAsync(key);   if (exist != null)  {   _context.Entry(exist).CurrentValues.SetValues(t);  var result = await Context.SaveChangesAsync();   if (result == 0) return null  }   return exist;  }