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

本文关键字:实体 是什么 类型 方法 复杂 框架 MVC | 更新日期: 2023-09-27 18:04:41

我通过Angularjs $resource使用PUT方法向我的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块,如果product包含任何计数器,它们都是重复的。product中的2个计数器将变成4个,以此类推。有什么问题吗?甚至我也在克隆计数器列表,但不知道为什么没有foreach的clear工作,而有了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条目。"、"类型":"System.Data.Entity.Core.OptimisticConcurrencyException"、"加":"在System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(其选项)' r ' nSystem.Data.Entity.Internal.InternalContext.SaveChanges ()"

这里是POST方法,了解更多信息。计数器实际上是重新添加到产品和其他复杂的属性,如文档和项目任务之间的关系。

 // 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);
        }
    }

:我想只保留到来的计数器,而不是更多的存在。是先清完再加新人吗?或者其他方法?

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

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

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