在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);
}
}
:我想只保留到来的计数器,而不是更多的存在。是先清完再加新人吗?或者其他方法?
在您的savechanges()之后,您应该使用。这个对我有用
db.Entry(projectTask).State = EntityState.Unchanged;