添加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;
            ...
        }
    }

我现在仍然得到具有相同键错误的多个对象。我如何分离国家,这样我就可以再次重新添加它(!),而不从数据库中删除它??

请帮忙!

添加EF对象作为外键

将国家附加到地址的最便宜的方法是使用存根来表示国家,然后将其附加到地址。在这种情况下,如果您只想附加现有的国家/地区而不编辑它,则可以避免往返数据库。

// 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属性表示一个外键。