我在MVC Web API中使用Entity Framework,我无法弄清楚为什么更改没有保存到数据库中。我使用以下代码:
[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)
这看起来非常像Entity Framework“认为”在数据库中生成Provision_Status_Text
列 - 要么是因为它是一个标识(不太可能是字符串列),要么是因为它是一个计算列。
对此的指示是:</ p>
虽然您更改了该列,但该列不是set
语句中update
表达式的一部分。如果该列是数据库生成的,那么这是预期的。
该列在sql select
表达式中返回。对于数据库生成列,这是预期的,因为EF希望在插入或更新后使用当前计算的数据库值更新客户端上的实体。
同样适用于select
语句中出现的其他列的方式。
如果您使用的是Code-First工作流程,请检查是否使用
之一注释了这些属性[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
属性或
....HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
....HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
与Fluent API一起使用。
如果您在EDMX中使用Database-First或Model-First工作流程,请检查EDMX文件中的StoreGeneratedPattern="Identity"
或StoreGeneratedPattern="Computed"
属性。您也应该在设计器表面中找到这些设置。
这并不一定意味着该列实际上是在数据库中生成的。但是,如果其中一个设置在模型元数据中,EF将假定它是并且表现得与您看到它的方式相同。这可能意味着数据库和模型由于某种原因“不同步”,因为在数据库模式或模型中已经完成了一些手动更改,可能没有更新另一方。