【发布时间】:2016-11-10 19:58:40
【问题描述】:
我有一个与Address 类有关系的Customer 类:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
public string Street1 { get; set; }
//Snip a bunch of properties
public virtual Customer Customer { get; set; }
}
我有一个编辑表单,其中显示了客户和地址的所有字段。当这个表单被提交时,它会调用控制器中的Edit 方法:
public ActionResult Save(Customer customer)
{
if (!ModelState.IsValid)
{
var viewModel = new CustomerFormViewModel
{
Customer = customer,
CustomerTypes = _context.CustomerTypes.ToList()
};
return View("CustomerForm", viewModel);
}
if (customer.Id == 0)
_context.Customers.Add(customer);
else
{
var existingCustomer = _context.Customers
.Include(c => c.Addresses)
.Single(c => c.Id == customer.Id);
existingCustomer.Name = customer.Name;
existingCustomer.TaxId = customer.TaxId;
existingCustomer.CustomerTypeId = customer.CustomerTypeId;
existingCustomer.CreditLimit = customer.CreditLimit;
existingCustomer.Exempt = customer.Exempt;
existingCustomer.Addresses = customer.Addresses;
}
_context.SaveChanges();
return RedirectToAction("Index", "Customers");
}
这不起作用并在数据库中的Addresses 表中创建重复条目。我想我明白为什么(EF 不够聪明,无法知道集合中的地址需要根据情况添加/修改/删除)。那么,解决此问题的最佳方法是什么?
我的直觉是,我需要遍历 Addresses 集合并手动比较它们,从表单中添加客户不存在的任何新集合,更新确实存在的集合,并删除不存在的集合由表单发送但存在于客户的数据库中。类似的东西(暂时忽略删除功能):
foreach(Address address in customer.Addresses)
{
if (address.Id == 0)
// Add record
else
// Fetch address record from DB
// Update data
}
// Save context
这是解决此问题的最佳方法,还是有任何 EF 技巧来迭代和同步子集合到数据库?
哦,还有一个让我摸不着头脑的问题 - 我可以理解如何在数据库中创建新的地址记录,但我不明白的是现有的地址记录也被更新为customer_id 设置为 NULL……这到底是怎么回事?这让我相信 EF 确实看到原始地址记录以某种方式链接(因为它正在修改它)但它还不够聪明,无法意识到我传入的记录应该替换它?
谢谢 -- 还有,这是 EF6 和 MVC5
【问题讨论】:
标签: c# asp.net-mvc entity-framework