【问题标题】:Adding EF object as a foreign key添加 EF 对象作为外键
【发布时间】:2014-07-26 02:02:42
【问题描述】:

好的,这几天我一直在纠结这个问题。

如何指示实体框架将对象作为外键插入现有对象,而不是作为全新对象?我已经尝试了各种各样的事情。我不断收到错误消息“ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。”

我只是想在地址中添加一个国家。这些国家都列在一个单独的数据库表中。该国家/地区来自 MVC 视图发布的下拉列表,因此我只有 ID。这意味着我可以获取对象的唯一方法是查询 EF,这会导致重复的对象。

希望有人可以提供帮助。啊!

M

=== 更多信息 ===

虽然上面指出只设置 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;
            ...
        }
    }

我现在仍然得到具有相同键错误的多个对象。如何分离国家/地区以便我可以重新添加它(!)而不将其从数据库中删除??

请帮忙!

M

【问题讨论】:

  • 能否请您发布CountryAddress 实体?

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


【解决方案1】:

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

例如

// 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 在 cmets 中所指出的,如果您的 Address-->Country 关系也具有外键 id 属性,您也可以通过以下方式实现:

address.CountryId = postedId;

当通过SaveChanges 方法调用DetectChanges 时,Entity Framework 将执行关系修复,并确保所有导航属性都设置正确。

【讨论】:

  • 值得一提的是,如果您的模型中存在address.CountryId,您也可以简单地设置它。
【解决方案2】:

尝试:

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

【讨论】:

  • 非常感谢您的回答。请参阅上面的更多信息。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 2018-03-31
    • 1970-01-01
    • 2022-12-28
    • 1970-01-01
    • 2014-11-01
    相关资源
    最近更新 更多