c# - 在 MVC Entity Framework 中 PUT 复杂实体类型的正确方法是什么

标签 c# entity-framework asp.net-mvc-4 asp.net-web-api put

我正在使用 PUT 方法通过 Angularjs $resource 向我的 ProductController 发送一个 json 请求。 产品已成功收到。问题是更新产品的复杂属性。 这是产品型号。

 Product{
    //other properties
    public virtual List<Bookmark> Bookmarks { get; set; }
    public virtual List<ProductCounter> Counters { get; set; }
 }

现在这是我的 Controller PUT 方法。

 public HttpResponseMessage PutProduct(int key, Product product)
    {
        if (!ModelState.IsValid)
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }

        if (key != product.ID)
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }

        product.ProductDocuments.Clear();
        var counters = new List<ProductCounter>(product.Counters);
        product.Counters.Clear();
        foreach (var counter in counters)
        {
            product.Counters.Add(counter);
            db.Entry(counter).State = EntityState.Added;

        }
        db.Entry(product).State = EntityState.Modified;

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
        }

        return Request.CreateResponse(HttpStatusCode.OK);
    }

如果我删除 foreach block ,所有计数器都会被删除。

如果我添加 foreach block ,如果 product 包含任何计数器,它们都会被复制。产品中的 2 个计数器将变为 4 个,依此类推。问题是什么?即使我正在克隆计数器列表,但不知道为什么在没有 foreach 的情况下清除,而用 foreach 清除的计数器又回来了。即使我尝试在 foreach 中将计数器的 ID 设置为 0,但这也会重复记录。

我在 counters.clear() 之后尝试过这个版本的 foreach;

  foreach (var counter in counters)
        {
            product.Counters.Add(new ProductCounter(){Name=counter.Name,Value=counter.Value});
        }

这给出了这个错误响应:

""innererror":{ "message":"An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

"internalexception":{ "message":"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.","type":"System.Data.Entity.Core.OptimisticConcurrencyException","stacktrace":" at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)\r\n at System.Data.Entity.Internal.InternalContext.SaveChanges()"

这是 POST 方法,以获取更多信息。计数器实际上是重新添加到产品和其他复杂属性(如 Documents 和 ProjectTasks)有关系。

 // POST api/Product
    public HttpResponseMessage PostProduct(Product product)
    {
        if (ModelState.IsValid)
        {
            db.Products.Add(product);
            foreach (var projectTask in product.ProjectTasks)
            {
                db.ProjectTasks.Attach(projectTask);
            }
            foreach (var bookmark in product.Bookmarks)
            {
                db.Bookmarks.Attach(bookmark);
            }
            foreach (var document in product.ProductDocuments)
            {
                db.Documents.Attach(document);
            }
            //No attachment for counters, they are added as a list. if I remove all attachments for other entities, these entities get duplicated in their own tables.


            db.SaveChanges();

            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, product);
            //response.Headers.Location = new Uri(Url.Link("DefaultApi", new { key = product.ID }));
            return response;
        }
        else
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }
    }

问题: 我只想保留即将到来的柜台,而不是更多的现有柜台。是不是先清完再加新人?还是其他方法?

最佳答案

在你的 savechanges() 之后你应该使用。这个对我有用

db.Entry(projectTask).State = EntityState.Unchanged;

关于c# - 在 MVC Entity Framework 中 PUT 复杂实体类型的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827507/

相关文章:

c# - 基于 MVC4 WebApi 的 LINQPad

asp.net - Angularjs html5Mode页面刷新打破了asp.net mvc中的路由

c# - 在 Windows 10 IOT 中安全保存文件

asp.net - Entity Framework 隐藏n到n表

c# - 将值添加到动态填充的列表 c#

c# - Entity Framework 。违反 UNIQUE KEY 约束

asp.net-mvc - 带有 MVC4 模型绑定(bind)的 Angular JS 因日期/日期时间而失败?

c# - 使用 AutoFixture/AutoMoq 为深度嵌套的类创建模拟?

c# - Windows服务计时器多线程

c# - 为什么后台线程会阻塞GUI