繁体   English   中英

在MVC实体框架中PUT复杂实体类型的正确方法是什么

[英]What is the correct way to PUT a complex entity type in MVC Entity Framework

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

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

现在这是控制器的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块,则删除所有计数器。

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

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

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

这会给出这个错误:

“”innererror“:{”message“:”保存未公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常源。 通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。 有关详细信息,请参阅InnerException。

“internalexception”:{“message”:“存储更新,插入或删除语句影响了意外的行数(0)。实体可能已被修改或删除,因为实体已加载。刷新ObjectStateManager条目。”,“type”: System.Data.Entity.InternalContext中的“System.Data.Entity.Core.OptimisticConcurrencyException”,“stacktrace”:“at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)\\ r \\ n”。保存更改()”

以下是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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM