РЕДАКТИРОВАТЬ:
Я только что понял, что SaveChangesAsync, возвращающий 0, не означает, что он потерпел неудачу, структура сущности всегда будет генерировать исключение, когда что-то не так, поэтому проверка, если SaveChanges == 0лишний!Изменения сохранения всегда должны возвращать 1 в примере ниже, если что-то не получается, тогда генерируется исключение.
Однако бывают случаи, когда используется что-то еще, и это не является структурой сущности, поэтому этот вопрос для.
Серверы могут выйти из строя, при помещении всего моего кода доступа к данным в контроллеры, я могу справиться с этим следующим образом:
[HttpPost]
public async Task<ActionResult<Item>> CreateAsync([FromBody] Item item)
{
await _dbContext.AddAsync(item);
if (await _dbContext.SaveChangesAsync() == 0)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
return CreatedAtAction(nameof(GetAsync), new { id = item.Id }, item);
}
Как мне поступить, когда мой доступ к данным инкапсулирован на уровне сервиса?
public class ItemsService
{
public async Task<Item> CreateAsync(Item item)
{
await _dbContext.AddAsync(item);
if (await _dbContext.SaveChangesAsync() == 0)
{
return null;
}
return item;
}
}
Тогда это будет использоваться следующим образом:
[HttpPost]
public async Task<ActionResult<Item>> CreateAsync([FromBody] Item item)
{
// model state validation skipped for the sake of simplicity,
// that would return BadRequest or some more valuable information
var item = await _itemsService.CreateAsync(item);
if (item == null)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
return CreatedAtAction(nameof(GetAsync), new { id = item.Id }, item);
}
Может быть, это работает для точного создания, потому что есть только 2 кода состояния, но давайте рассмотрим обновление, где может быть больше 2Возможные ошибки, такие как:
- Не найдено (404)
- Внутренняя ошибка сервера (500)
- Ok (200)
Кодбез услуг:
[HttpPut("{id}")]
public async Task<ActionResult<Item>> UpdateAsync(int id, [FromBody] Item itemToUpdate)
{
var item = await _dbContext.Items.FindAsync(id);
if (item == null)
{
return NotFound();
}
// update item with itemToUpdate
//...
await _dbContext.Update(item);
if (await _dbContext.SaveChangesAsync() == 0)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
return item;
}
Теперь со службами это не может быть должным образом обработано:
public class ItemsService
{
public async Task<Item> UpdateAsync(Item updateItem)
{
var item = await _dbContext.Items.FindAsync(id);
if (item == null)
{
return null;
}
//change some properties and update
//...
_dbContext.Items.Update(item);
if (await _dbContext.SaveChangesAsync() == 0)
{
// what now?
}
return item;
}
}
, потому что оно всегда возвращает ноль, и нет никакого способа узнать, был ли элемент не найден илисохранение не удалось.
Как я могу правильно с ним справиться?
Примечание. Я не добавил DTO или что-то подобное, чтобы этот пример был простым.