我有以下简单的案例,其中客户端与 .NET Web API 进行通信:
我无法实施第 5 步。 这是我正在使用的代码:
[HttpPut]
[ActionName("Update")]
public IHttpActionResult Update(MyModel myModel)
{
this.context.MyModel.Attach(myModel);
this.context.SubmitChanges();
return Ok();
}
此代码不起作用。
我们还知道 WebAPI 的端点是无状态的。
我见过其他类似的解决方案:
[HttpPut]
[ActionName("Update")]
public IHttpActionResult Update(MyModel myModel)
{
this.context.MyModel.Add(myModel);
this.context.Entry(myModel).State = System.Data.Entity.EntityState.Modified;
this.context.SaveChanges();
return Ok();
}
但是这段代码的问题是我使用的
System.Data.Linq.DataContext
没有属性 Entry
。System.Data.Linq.DataContext
来做到这一点?
更新: 我已经按照@Alexander 的建议尝试了以下方法:
this.context.MyModel.Attach(myModel, true);
context.SubmitChanges();
这将返回以下错误:
An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy.
,这可能是由于上下文现在已更改。
然后我尝试了以下方法:
var currentDbModel = this.context.MyModel.GetByKey(myModel.ID);
this.context.MyModel.Attach(myModel, currentDbModel);
context.SubmitChanges();
但这会引发以下错误:
"Cannot add an entity with a key that is already in use."
现在有效的是以下代码:
var currentDbModel = this.context.MyModel.GetByKey(myModel.ID);
this.context = new DataContext(this.cnn);
this.context.MyModel.Attach(myModel, currentDbModel);
context.SubmitChanges();
上面代码的问题是,首先我必须再次从数据库中获取当前记录,然后更新数据上下文。我想知道这是否可以以某种方式优化?
您必须手动更新现有模型的属性。
[HttpPut]
[ActionName("Update")]
public IHttpActionResult Update(MyModel myModel)
{
// Assuming myModel.Id is how you identify your object
var existing = this.context.MyModel.FirstOrDefault(m => m.Id == myModel.Id);
if (existing == null)
{
return NotFound();
}
// Update properties
existing.Property1 = myModel.Property1;
existing.Property2 = myModel.Property2;
// Repeat for other properties you need to update
// Submit the changes
this.context.SubmitChanges();
return Ok();
}
如果单独映射属性的想法看起来很繁重,您可以使用像 AutoMapper 这样的库,或与此类似的 Reflection 代码:
private void UpdateModelProperties(MyApiModel source, MyApiModel destination)
{
var properties = typeof(MyApiModel).GetProperties();
foreach (var property in properties)
{
if (property.CanWrite)
{
var newValue = property.GetValue(source, null);
property.SetValue(destination, newValue, null);
}
}
}