Я использую реализацию на основе API для Entity Framework; Объекты EF передаются в DTO (объекты передачи данных) перед отправкой для потребления клиенту.ObjectStateEntry не обновляется, пока не проверю db.Entry
На обратном пути я возвращаюсь от DTO к моим типам сущностей; У меня возникают проблемы с проверкой параллелизма по вызовам DELETE/UPDATE. Я использую EF 6 и webAPI 2.
Что происходит, после загрузки объекта из базы данных я должен сделать вызов db.Entry (object) до того, как запись состояния объекта фактически изменится на «Модифицированный», ,
Код:
[Route("")]
[HttpDelete]
[ResponseType(typeof(void))]
public async Task<IHttpActionResult> DeleteAssetType(long id, DateTimeOffset modifyDate)
{
try
{
AssetType assetType = await db.AssetTypes.FindAsync(id);
if (assetType == null)
{
return NotFound();
}
//Set modifyDate to match what API received and then mark record for deletion
ObjectStateEntry ose = ((IObjectContextAdapter) db).ObjectContext.ObjectStateManager.GetObjectStateEntry(assetType);
assetType.ModifyDate = modifyDate;
ose.AcceptChanges();
db.AssetTypes.Remove(assetType);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
//TODO Handle Concurrency Exception Specifically (if needed)
throw;
}
}
catch(Exception ex)
{
//TODO Add Error Handling Code
throw;
}
//return Ok(assetType);
return Ok();
}
... и проблема заключается в том, что после вызова assetType.ModifyDate = ModifyDate (это мой параллелизм рисунок), если я смотрю на ose.State, это "Без изменений" , Если, однако, через отладчик, я смотрю на db.Entry (assetType), а THEN смотрят на ose, в этот момент ose правильно скажет «Модифицировано».
Основная проблема заключается в том, что вызов ose.AcceptChanges() ничего не делает, поскольку он видит объект как Unmodified.
Я могу исправить это, просто позвонив db.Entry (assetType) и выполняя буквально НИЧЕГО с результирующим объектом, и с этого момента он работает безупречно, но это, кажется, предполагает, что я делаю что-то неправильно в другом месте, поскольку FindAsync утверждает, что он привязывает объект к контексту, и поэтому мне не нужно вызывать .Entry, прежде чем запрашивать состояние.
В качестве расширенного примера того, что я имею в виду, если я делаю следующее:
...
assetType.ModifyDate = modifyDate;
var state = db.Entry(assetType).State; /* ADDED THIS LINE */
ose.AcceptChanges();
....
... то вызов ose.AcceptChanges() делает именно то, что я ожидал. Мой вопрос/вопрос: ПОЧЕМУ я должен вызвать db.Entry (assetType), чтобы система увидела объект как измененный? Разве это еще не привязано к контексту с помощью FindAsync раньше, и не следует ли автоматически перехватывать изменение в файл modifyDate? Если это имеет значение, это db-first с файлом edmx, а не первым.
EDIT: Изменено, чтобы включить полный код для функции Delete API.
EDIT 2: Уточнено. Что я прошу/что делает эту работу/вопрос.
Это работает в том смысле, что государство говорит «Модифицировано». Проблема, с которой я борюсь, заключается в том, что я имею в виду Remove; то, что я хочу сделать, это удалить объект из базы данных, если поле изменения даты в базе данных соответствует тому, что получил API. Я изменю свой вопрос, чтобы сделать его более понятным - проблема, с которой я сталкиваюсь, заключается в том, что мне, кажется, нужно вызвать db.Entry (assetType), независимо от того, что я делаю с результатом вызова, до состояние действительно правильно настроено для модификации. – SooperGenius