【问题标题】:Entity Framework Attach Exception caused by automatic recursive attaching of referenced entities引用实体的自动递归附加导致的实体框架附加异常
【发布时间】:2016-09-14 12:04:21
【问题描述】:

我有两个分离的实体,它们已经急切地加载了多个其他实体。 (1 到 n 关系)。

引用分离实体(存储在 ICollection 导航属性中)的热切加载实体可以同时存在于两个分离实体中。

当我想附加两个分离的实体时,我得到一个异常,因为急切加载的实体已经附加。

这是用 cmets 解释问题的示例代码:

public ProvokeAttachException()
{
    //s1 and s2 share some of their samples
    sample_set s1 = GetSampleSet(1);
    sample_set s2 = GetSampleSet(2);

    //Do some stuff

    //Attaching the sample_sets again
    using(StationContext context = new StationContext())
    {
        // Fine
        context.sample_set.Attach(s1);

        //Throws Exception because some of the included samples in sample_set
        //have been attached automatically with s1
        context.sample_set.Attach(s2); 
    }

}

public sample_set GetSampleSet(int setId)
{
    //Eager Loading all samples that reference sample_set (1 to n relation)
    using (StationContext context = new StationContext())
    {
        return context.sample_set.Include("sample").FirstOrDefault(s => s.id = setId);
    }
}

我怎样才能毫无例外地附加两个实体?

【问题讨论】:

  • 您能否提供有关您的数据建模的更多信息。您可能需要对其进行一些重构。如果对象已经附加,则不能再次附加。
  • @PedroSouki 我知道我不能再次附加实体。我有一个新的上下文,附加 s1 和 s2 是我做的第一件事,所以它们已经不能附加了。这是因为“样本”实体被急切加载,其中一些被 s1 和 s2 共享。 Attach 以递归方式自动附加所有包含在导航属性中的引用实体。我不知道如何避免异常以及 s1 和 s2 中包含的所有实体都已附加
  • @FelixKeil 我面临类似要求的挑战。我只是想知道你是否还记得你是如何解决这个挑战的。我非常感谢你的建议。
  • @user1814131 不幸的是,我不记得我们的解决方法是什么,我也无法再访问代码库了。

标签: c# entity-framework


【解决方案1】:

问题是附加的东西,改用Add。

当您执行context.sample_set.Attach(s1); 时,它真正做的是在新上下文中创建所有相关对象的实例,然后将它们添加到 sample_set,这就是它起作用的原因。

当您尝试context.sample_set.Attach(s2); 时,它会尝试再次创建所有共享的samples,这就是它抛出异常的原因。

所以我给你的建议是:

context.sample_set.Add(s1);
context.sample_set.Add(s2);
context.SaveChanges();

希望对你有帮助。

【讨论】:

  • 感谢您的回答!但 Add 用于在数据库中添加/插入新条目。 s1 & s2 存在于数据库中,仅与上下文分离,需要再次附加。所有共享样本和非共享样本都已存在于数据库中。所以我显然需要一个 Attach 而不是 Add
  • 我不明白您为什么需要分离实体。如果您只想编辑检索数据,请进行更改设置 context.Entry(obj).State = EntityState.Modified; 和 SaveChanges
  • 使用 Attach 的一般原因是实体不必再次检索,但可以像从 db 中检索一样使用,并且不需要数据库事务。例如。如果您将一些附加实体与分离实体连接起来,NavigationProperties 将不起作用
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
  • 2023-03-03
相关资源
最近更新 更多