将EF对象添加为外键

时间:2014-07-25 11:22:03

标签: c# asp.net-mvc entity-framework

好的,我已经把头发拉了几天了。

如何指示实体框架将对象作为外键插入现有对象,而不是作为一个全新的对象?我尝试过各种各样的事情。我不断收到错误" 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;
            ...
        }
    }

我现在仍在使用相同的键错误获取多个对象。我如何分离国家,以便我可以重新添加它(!)而不将其从数据库中删除?

请帮忙!

中号

3 个答案:

答案 0 :(得分:1)

将国家/地区附加到地址的最便宜方式是使用存根来表示您随后附加到该地址的国家/地区。 这样可以避免在这种情况下往返数据库,只需要在不编辑的情况下附加现有国家/地区。

E.g。

// 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在评论中所指出的,如果您的地址 - &gt;国家/地区关系也具有外键ID属性,您还可以实现以下相同:

address.CountryId = postedId;

当通过DetectChanges方法调用SaveChanges时,实体框架将执行关系修正,并确保正确设置所有导航属性。

答案 1 :(得分:0)

尝试:

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();
      }

答案 2 :(得分:0)

使用 ForeignKey 属性。这样你就可以分配一个id而不是整个对象。只需在类中包含一个int属性,并使用属性表示int属性表示外键来装饰navigation属性。