2013-07-19 83 views
1

我在MVC Web API中使用實體框架,我無法弄清楚爲什麼這些更改沒有保存到數據庫中。我使用下面的代碼:數據庫不會在實體上使用Savechanges方法更新

[HttpPost] 
public HttpResponseMessage PostPXE(PXE pxe) 
{ 
    var pxeRequestID = 
     from qsp in db.Queue_Server_Provision 
      .Where(a => a.Server_Name == pxe.Server_Name) 
     join isni in db.IaaS_Server_NIC_Information 
      .Where(a => a.MAC == pxe.Mac_Address) 
     on qsp.IaaS_ID equals isni.IaaS_Server_Information_IaaS_ID 
     select qsp.Request_ID; 

    var QSP = db.Queue_Server_Provision.Find(pxeRequestID.FirstOrDefault()); 

    db.Queue_Server_Provision.Attach(QSP); 
    QSP.Provision_Status_Code = "240.9"; 
    db.Entry(QSP).State = EntityState.Modified; 

    try 
    { 
     db.SaveChanges(); 
    } 
    catch (DbUpdateConcurrencyException e) 
    { 
     return Request.CreateResponse(HttpStatusCode.NotFound, e.Message); 
    } 
    catch (Exception e) 
    { 
     return Request.CreateResponse(HttpStatusCode.NotFound, "error"); 
    } 

    return Request.CreateResponse(HttpStatusCode.OK); 
} 

在調試一切似乎直到我打電話調用SaveChanges()方法,在這一點上Provision_Status_Code值恢復到它以前被修改什麼好工作。

下面的SQL從實體框架生成:

exec sp_executesql 
    N'update [dbo].[Queue_Server_Provision] 
     set [Server_Name] = @0, 
      [Environment_List_ID] = @1, 
      [Operating_System_List_ID] = @2, 
      [Container_Size_List_ID] = @3, 
      [Active_Directory_List_ID] = @4 
     where ([Request_ID] = @5) 
     select [IaaS_ID], 
      [Provision_Status_Code], 
      [Provision_Status_Text], 
      [Provision_Phase], 
      [Last_Update_Time], 
      [Canceled] 
     from [dbo].[Queue_Server_Provision] 
     where @@ROWCOUNT > 0 and [Request_ID] = 5', 
    N'@0 nvarchar(16), 
     @1 uniqueidentifier, 
     @2 uniqueidentifier, 
     @3 uniqueidentifier, 
     @4 uniqueidentifier, 
     @5 uniqueidentifier', 
    @0=N'IaaSTest222', 
    @1='31097372-E4A6-461D-AFCC-BFAF069A6710', 
    @2='CF44FE08-56DE-4A7D-813A-08A7AD215E8B', 
    @3='15AEB74F-E0CB-4219-AC69-8C623DE8DF46', 
    @4='EA08BB7E-5C1F-4F6B-83D6-4BF9F6C55FF7', 
    @5='34CA5F9C-2BF8-40E5-8BDD-5DE7364C18C3' 
+0

你得到了什麼錯誤?和哪裏(在哪一行)? –

+0

我沒有收到任何錯誤。一切都很好。 如果我改變'db.SaveChanges(); 'to int int rowsUpdated = db.SaveChanges();'rowsUpdated的值爲1. –

+0

成功執行上面的代碼後,數據庫保持不變。 –

回答

0

這看起來非常像實體框架「認爲」該Provision_Status_Text列在數據庫中生成的 - 要麼是因爲它是一個標識(不可能的字符串列)或因爲它是一個計算列。

適應症是這樣的:雖然你改變了列

  • 列不在update聲明set表達的一部分。如果該列是數據庫生成的,則這是預期的。

  • 該列在sql select表達式中返回。對於數據庫生成的列,這是預期的,因爲EF想要在插入或更新後使用當前計算的數據庫值更新客戶端上的實體。

這同樣適用於select語句中發生的其他列的方式。

如果使用代碼優先的工作流程檢查,如果這些屬性被註釋與

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
[DatabaseGenerated(DatabaseGeneratedOption.Computed)] 

屬性中的一個或者

....HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) 
....HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed) 

是使用流利的API。

如果您在EDMX中使用Database-First或Model-First工作流,請檢查EDMX文件中的StoreGeneratedPattern="Identity"StoreGeneratedPattern="Computed"屬性。你也應該在設計器表面找到這些設置。

這並不一定意味着該列實際上是在數據庫中生成的。但是,如果其中一個設置位於模型元數據中,EF將假定它是並且按照您看到的方式行事。這可能意味着數據庫和模型出於某種原因「不同步」,因爲已經在數據庫模式或模型中進行了一些手動更改,可能沒有更新另一側。

相關問題