2017-01-09 3 views
0

Я использую реализацию на основе 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: Уточнено. Что я прошу/что делает эту работу/вопрос.

ответ

0

Попробуйте это:

AssetType assetType = await db.AssetTypes.FindAsync(id); //get object from db 
assetType.ModifyDate = modifyDate; //modify it 
var state = db.Entry(assetType).State; //get current state, which should be Modified 
var updatedRecords = await db.SaveChangesAsync(); 

Проблема, кажется, что состояние вы получили было до того, любые изменения, сделанные в сущности. Кстати, метод Remove (https://msdn.microsoft.com/en-us/library/gg679171(v=vs.113).aspx) отмечает сущность как удаленную, поэтому я не думаю, что это то, что вы хотите.

+0

Это работает в том смысле, что государство говорит «Модифицировано». Проблема, с которой я борюсь, заключается в том, что я имею в виду Remove; то, что я хочу сделать, это удалить объект из базы данных, если поле изменения даты в базе данных соответствует тому, что получил API. Я изменю свой вопрос, чтобы сделать его более понятным - проблема, с которой я сталкиваюсь, заключается в том, что мне, кажется, нужно вызвать db.Entry (assetType), независимо от того, что я делаю с результатом вызова, до состояние действительно правильно настроено для модификации. – SooperGenius