有点背景知识,我在数据库中有2个表,它们通过联结表共享多对多关系。几乎与this blog post中列出的情景相同。
我将使用一个非常简单的例子来说明我正在尝试做的事情。当我的Web应用程序上的用户想要创建订单时,他们可以访问要在发布之前添加到订单的产品列表。此产品列表通过REST API调用获取,并作为JSON数据提供给客户端应用程序。
当我发布订单时出现问题,实体框架工作尝试重新保存我的集合中的产品而不是创建关联。
考虑我的控制器和UnitOfWork类的以下非常简化的代码示例。
public class OrdersController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
private readonly IOrderRepository _orderRepository;
public OrdersController(IUnitOfWork unitOfWork, IOrderRepository orderRepository)
{
_unitOfWork = unitOfWork;
_orderRepository = orderRepository;
}
// POST api/Orders
public Dto.Get.Order Post(Dto.Post.Order postOrder)
{
Models.Order modelOrder = new Model.Order();
modelOrder.Name = postOrder.Name;
modelOrder.Description = postOrder.Description;
foreach (var getProduct in postOrder.Products)
{
Models.Product modelProduct = new Models.Product();
modelProduct.Id = getProduct.Id;
getProduct.Name = getProduct.Name;
getProduct.Price = getProduct.Price;
modelOrder.Products.Add(modelProduct);
}
modelOrder.AccountId = 999;
_orderRepository.Insert(modelOrder);
_orderRepository.Save();
_unitOfWork.SaveChanges();
//Return new Order as it exists in DB
return Get(modelOrder.Id);
}
}
public class UnitOfWork : IUnitOfWork
{
public MyApplicationContainer Context { get; set; }
public UnitOfWork(MyApplicationContainer context)
{
Context = context;
this.Context.Configuration.ProxyCreationEnabled = false;
this.Context.Configuration.LazyLoadingEnabled = false;
}
public void SaveChanges()
{
Context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
if (disposing)
Context.Dispose();
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
注意:为简单起见,我没有费心发布我的帖子和获取DTO,或者我的模型发布订单和产品实体。
一个有趣的观察,如果我根据传入的ID获取产品的模型版本,然后将其分配给要保存的集合,它可以正常工作。但这对我来说似乎非常“健谈”,因为订单可能有数百种产品。例如:
foreach (var getProduct in postOrder.Products)
{
var modelProduct = _productRepository.Get(getProduct.Id);
modelOrder.Products.Add(modelProduct);
}
答案 0 :(得分:1)
您正在使用new运算符明确创建新产品。显然EF尝试在数据库中创建新产品。您需要在数据库中查询产品,但是您应该使用一个查询来执行此操作。
的内容var productsIDs = postOrder.Products.Select(p => p.ID).ToArray();
var actualProducts = from p in product
where productsIDs.Contains(p.ID)
select p;