添加EF对象作为外键
本文关键字:EF 对象 添加 | 更新日期: 2023-09-27 18:14:53
好吧,这几天我一直为这件事烦恼。
我如何指示实体框架插入一个对象作为一个外键到一个现有的对象,而不是作为一个全新的对象?我已经尝试了各种各样的方法。我一直得到错误"具有相同键的对象已经存在于ObjectStateManager中。ObjectStateManager不能跟踪具有相同键的多个对象。"
我只是想给地址加上一个国家。这些国家都列在一个单独的数据库表中。国家来自MVC视图发布的下拉列表,所以我只有ID。这意味着我能得到这个对象的唯一方法是查询EF,结果是一个重复的对象。
希望有人能帮忙。Aaarg !
===更多信息===
虽然上面非常正确地指出只设置countryID,但这只适用于创建场景。
我在控制器中有这个:
public ActionResult Edit(SiteViewModel siteViewModel)
{
if (ModelState.IsValid)
{
Site site = _unitOfWork.SiteRepository.GetById(siteViewModel.SiteID);
_unitOfWork.Detach(site);
site = Mapper.Map<SiteViewModel, Site>(siteViewModel);
site.CountryId = siteViewModel.CountryId;
...
}
}
我现在仍然得到具有相同键错误的多个对象。我如何分离国家,这样我就可以再次重新添加它(!),而不从数据库中删除它??
请帮忙!
将国家附加到地址的最便宜的方法是使用存根来表示国家,然后将其附加到地址。在这种情况下,如果您只想附加现有的国家/地区而不编辑它,则可以避免往返数据库。
。
// Create stub country using posted country id
var country = new Country { Id = postedId };
// Attach (NOT ADD) to context as an existing entity
// (Using Add would lead to an EntityState of Added and a violation of the
// PK unique constraint as per the question)
context.Countries.Attach(country)
// This assumes the address is attached to the context
// I.e. either its been Added to the Address DbSet
// or returned from a query on the Address DbSet
address.Country = country
context.SaveChanges();
正如Iain Galloway在评论中指出的那样,如果您的Address->Country关系也具有外键id属性,您也可以实现以下相同的操作:
address.CountryId = postedId;
当通过SaveChanges
方法调用DetectChanges
时,实体框架将执行关系修复,并确保所有导航属性设置正确。
try:
var id = 2; // id of item
using (var context = new Context())
{
var item = context.YourTable.Single(m => m.Id== id);
item.ForeinKey = someNewForeinKey;
context.SubmitChanges();
}
使用ForeignKey属性。这样你就可以分配一个id而不是拥有整个对象。只要在你的类中包含一个int属性,并在导航属性中添加一个int属性表示一个外键。