У меня есть список объектов. Эти объекты и некоторые из их свойств отображаются в виде сетки. Пользователь может добавлять, удалять и изменять свойства любого выбранного объекта.
Подход к обновлению выполняется при нажатии кнопки сохранения (а не сразу с предпринятыми действиями).
Как лучше всего обновить список, который может включать добавленные объекты, удаленные объекты и объекты с измененными свойствами в моем веб-API 2 с помощью Entity Framework?
Класс клиента:
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
}
Класс клиентов:
Public Class Customers
{
public List<Customer> Customers { get; set; }
}
Метод PUT для клиентов на данный момент:
ResponseType(typeof(void))]
public async Task<IHttpActionResult> PutCustomersViewModel(CustomersViewModel custViewModel)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
// Not sure how to iterate thru the list and update or add accordingly
_context.Entry(customer).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch(DbEntityValidationException ex)
{
foreach(var entityValidationErrors in ex.EntityValidationErrors)
{
foreach(var validationError in entityValidationErrors.ValidationErrors)
{
System.Diagnostics.Debug.WriteLine("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
}
}
}
catch(DbUpdateConcurrencyException)
{
return NotFound();
throw;
}
return StatusCode(HttpStatusCode.NoContent);
}
Я могу удалить все элементы и снова добавить их, но я считаю, что это неправильный подход. Есть ли способ сравнить и только добавить / обновить изменения / отсутствующие элементы?





Вы не хотите удалять и повторно добавлять объекты - это может фактически удалить то, что у вас есть в базе данных, и повторно добавить новые.
Вы можете перебирать объекты, чтобы найти те, которые находятся в обоих (обновление), и те, которые находятся в цели, но не в источнике (удалить), и те, которые находятся в источнике, но не в цели (создать). Пока вы идете, вы можете внести изменения в контекст БД, а затем просто сохранить изменения.
Вы можете использовать что-то вроде AutoMapper.org, извлечь коллекцию объектов базы данных, которые вы хотите отредактировать, объединить с помощью automapper, а затем сохранить изменения.
Это просто моя точка зрения, если ее трудно реализовать, возможно, это потому, что метод пытается сделать слишком много.
Такой подход создаст дрянной код с проблемами обслуживания.
Лучше всего разделить это на 3 метода: создание, обновление и удаление.
И поместите это действие прямо в строку вашей сетки данных или событие catch при изменении сетки данных, чтобы правильно применить изменения к вашему методу сохранения в вашем представлении.
да, я знаю, может быть, я ищу что-то вроде источника событий, и сохранение отправит ваши события, и ваша точка входа должна их выполнить
Сделайте это так, как сказал @Jouan Antoine ... кнопки для каждого действия CRUD или проверьте состояние объекта:
switch (custViewModel.State)
{
case State.Added:
break;
case State.Unchanged:
break;
case State.Modified:
break;
case State.Deleted:
break;
case State.Detached:
break;
}
ваша сетка:
Не могли бы вы подробнее рассказать об этом. Мне не разрешено совершать какие-либо транзакции с базой данных, пока пользователь не будет уверен в своих изменениях в сетке.
Я не уверен, что вы имеете в виду в отношении уверенности в своих изменениях в сетке ?? Вы должны применить проверку (как на стороне клиента, так и на стороне сервера) перед выполнением любых транзакций. Это обеспечит соблюдение ваших бизнес-правил.
Под «уверенностью» я подразумеваю, что пользователи должны иметь возможность отменить все изменения, которые они внесли до «сохранения» своих изменений. Они должны иметь возможность отменить некоторые или все свои изменения до того, как они будут сохранены в базе данных. Следовательно, у меня может быть только одна кнопка, которая выполняет все изменения в этом конкретном сценарии. Таким образом, вы можете изменить фамилию и другой номер телефона, а затем добавить нового клиента, и это нормально, но эти действия не могут быть быстро сохранены, и они могут происходить только вместе.
Это будет сложно сделать без сохранения предварительных изменений в базе данных. Я настоятельно рекомендую создать промежуточные таблицы в вашей базе данных и сохранить изменения в этих таблицах. После того, как пользователь примет изменения, переместите данные из промежуточных в реальные таблицы. Вам нужен способ сохранить все до нажатия кнопки принятия. Как вы выполняете свои действия CRUD, такие как добавление и обновление? Вы должны предоставить пользователю способ ввода / изменения информации и ее сохранения.
Я сохраняю все изменения в списке объектов (List <Customer>) в памяти до того, как пользователь нажмет кнопку подтверждения. Я удивлен, потому что ожидал, что обновление списка в EF будет намного проще. У меня нет проблем с операциями CRUD для сущностей с отдельными элементами, но если мне нужно обновить список элементов в сущности, проходящей несколько этапов, кажется, много работы для того, чем должен был быть EF.
Он предназначен для одновременной обработки одного объекта. Вы можете выполнить foreach в списке и просто SaveChanges () для каждого элемента в коллекции. Не очень эффективно. Вы должны реализовать транзакцию для отката изменений. Я думаю, что это в context.Database.BeginTransaction ()
В идеале вы правы, однако бизнес-требования указывают, к сожалению, на то, чтобы разрешить пользователям играть с контентом (вносить изменения, удалять и добавлять), чтобы получить то, что они хотят, прежде чем фактически сохранить его. Еще один недостаток - транзакция базы данных для каждого действия пользователя, а этого было бы слишком много для этой сетки.