2013-07-19 80 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将假定它是并且按照您看到的方式行事。这可能意味着数据库和模型出于某种原因“不同步”,因为已经在数据库模式或模型中进行了一些手动更改,可能没有更新另一侧。

相关问题