2017-01-09 43 views
0

我正在使用基于API的实施框架的实施;在发送给客户端之前,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),然后看看ose,那么这个点就会正确地说出“Modified”。

核心问题是对ose.AcceptChanges()的调用什么也不做,因为它将对象视为未修改。

我可以通过调用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文件,而不是代码第一。

编辑:修改为包含删除API函数的完整代码。

编辑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(); 

这个问题似乎是,你所获得的状态是任何变化对实体才制成。 顺便说一下,方法删除(https://msdn.microsoft.com/en-us/library/gg679171(v=vs.113).aspx)标记为删除的实体,所以我不认为这就是你想要的。

+0

这个作品的意思是国家确实说“修改”。但是,我正在努力解决的问题是我的意思是删除;我想要做的是从数据库中删除对象如果数据库中的modify-date字段与API收到的内容匹配。 我会修改我的问题,使其更清楚一点 - 我遇到的问题是,我似乎必须调用db.Entry(assetType),无论我如何处理调用的结果,在状态实际上正确地将其自身设置为修改。 – SooperGenius