如何使用 Linq-To-SQL 但使用 System.Data.Linq.DataContext 更新对象

问题描述 投票:0回答:1

我有以下简单的案例,其中客户端与 .NET Web API 进行通信:

  1. 客户端向 Web API 发出对象请求,并提供所请求的 ID。
  2. Web API 将对象返回给客户端。
  3. 客户端更改对象的多个属性。
  4. 客户端使用 PUT 方法将对象(而不是更改的属性)发送回 Web API。
  5. Web API 必须使用 linq-to-sql 来更新数据库。

我无法实施第 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();

上面代码的问题是,首先我必须再次从数据库中获取当前记录,然后更新数据上下文。我想知道这是否可以以某种方式优化?

c# asp.net-web-api linq-to-sql
1个回答
0
投票

您必须手动更新现有模型的属性。

[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);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.