我目前正在构建一个ASP.NET MVC 5应用程序,其中EF 6.1.3链接到SQL Server数据库。
我的问题:当我尝试保存“PurchaseInvoiceSplitsViewModel”的2个或更多实例时,我收到以下错误,只保存1个时没问题。
无法确定'WebAS.Models.PurchaseInvoiceSplits_VehicleStock'关系的主要结尾。 多个添加的实体可能具有相同的主键。
问题出现在第_context.SaveChanges();
行
我的ViewModel:
public class PurchaseInvoiceHeaderFormViewModel
{
public PurchaseInvoiceHeaderFormViewModel()
{
Splits = new List<PurchaseInvoiceSplitsViewModel>();
}
public List<PurchaseInvoiceSplitsViewModel> Splits { get; set; }
}
public class PurchaseInvoiceSplitsViewModel
{
public PurchaseInvoiceSplits PurchaseInvoiceSplits { get; set; }
public VehicleInformation VehicleInformation { get; set; }
public VehicleStock VehicleStock { get; set; }
}
我的模特:
public class VehicleStock
{
[Key]
public int VehicleStockId { get; set; }
public int VehicleInformationId { get; set; }
public VehicleInformation VehicleInformation { get; set; }
}
public class PurchaseInvoiceSplits
{
[Key]
public int PurchaseInvoiceSplitsId { get; set; }
public int? VehicleStockId { get; set; }
public VehicleStock VehicleStock { get; set; }
}
public class VehicleInformation
{
[Key]
public int VehicleInformationId { get; set; }
}
控制器:
[HttpPost]
public ActionResult Save(PurchaseInvoiceHeaderFormViewModel viewModel)
{
_context.PurchaseInvoiceHeader.Add(viewModel.PurchaseInvoiceHeader);
foreach (var Split in viewModel.Splits)
{
Split.PurchaseInvoiceSplits.VehicleStockId =
Split.VehicleStock.Id;
Split.VehicleStock.VehicleInformationId =
Split.VehicleInformation.Id;
_context.VehicleInformation.Add(Split.VehicleInformation);
_context.VehicleStock.Add(Split.VehicleStock);
_context.PurchaseInvoiceSplits.Add(Split.PurchaseInvoiceSplits);
}
_context.SaveChanges();
return RedirectToAction("xxx", "xxx");
}
我花了很多时间研究这个问题,我相信它与EF为模型分配临时Id的0有关。当有一个模型但似乎导致多个模型实例化的导航/参考问题时,这很好。对其他论坛帖子的回答建议使用我尝试过但尚未设法开始工作的临时Id。任何帮助将不胜感激。请随时要求进一步澄清/代码片段。
答案 0 :(得分:0)
使用实体框架事务解决问题(注意,似乎只适用于版本6+)。这里有非常有用的信息:
仅在Controller中需要修改:
[HttpPost]
public ActionResult Save(PurchaseInvoiceHeaderFormViewModel viewModel)
{
using (CustData Tcontext = new CustData())
{
using (DbContextTransaction transaction =
Tcontext.Database.BeginTransaction())
{
try
{
Tcontext.PurchaseInvoiceHeader.Add(viewModel.PurchaseInvoiceHeader);
Tcontext.SaveChanges();
foreach (var Split in viewModel.Splits)
{
Tcontext.VehicleInformation.Add(Split.VehicleInformation);
Split.VehicleStock.VehicleInformationId = Split.VehicleInformation.Id;
Tcontext.VehicleStock.Add(Split.VehicleStock);
Split.PurchaseInvoiceSplits.VehicleStockId = Split.VehicleStock.Id;
Split.PurchaseInvoiceSplits.PurchaseInvoiceNumberId = viewModel.PurchaseInvoiceHeader.Id;
Tcontext.PurchaseInvoiceSplits.Add(Split.PurchaseInvoiceSplits);
Tcontext.SaveChanges();
}
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine("Error occurred." + ex);
}
}
}
return RedirectToAction("xxx", "xxx");
}
我认为.Add发生的顺序也很重要,因此重新排列。
答案 1 :(得分:0)
我有相同的错误,并且代码设置不同,但是...
我看了看上面的答案,并注意到了底部的注释:我相信.add出现的顺序也很重要,因此需要重新排列。
我所做的是将保存的内容整理到我的代码中,并能够消除错误。我只是想将其发布以供将来进行错误搜索。