ObjectContext也在EF的打开上下文中处理

时间:2013-08-28 19:46:00

标签: c# entity-framework dispose

我有这种创建DataTable的方法:

private DataTable toDataTable<T>(IEnumerable<T> items)
    {
        var tb = new DataTable(typeof(T).Name);
        using (var context = new MyEntity())
        {
            PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var prop in props)
            {
                tb.Columns.Add(prop.Name, prop.PropertyType);
            }

            foreach (var item in items)
            {
                var values = new object[props.Length];
                for (var i = 0; i < props.Length; i++)
                {
                    values[i] = props[i].GetValue(item, null);
                }

                tb.Rows.Add(values);
            }
        }
       return tb;

    }

但它在第二个foreach中给了我这个错误:

  

ObjectContext实例已被释放,不能再用于需要连接的操作。

因为我打开了我的EF context;为什么会再次出现这个错误?

3 个答案:

答案 0 :(得分:3)

您传入IEnumerable<T>的{​​{1}}尚未实现。 toDataTable<T>()的背景已经处理完毕。您忘记了调用代码中的items

答案 1 :(得分:1)

如果items来自EntityFramework,那么它可能是罪魁祸首 - 它的上下文可能已经关闭。

你知道异常来自哪一行吗?

答案 2 :(得分:1)

我假设items集合包含来自EF的实体。这些项目最初属于ObjectContext,在您将它们传递给此方法之前显然已关闭。打开一个全新的背景并没有帮助,因为这不是这些项目所属的背景。

当你对其中一个实体使用反射时,它可能会试图懒惰地访问实体的导航属性,这需要数据库跳闸,但由于实体所属的上下文已经消失,因此数据库之旅不会发生

您可以将项目重新附加到新上下文,然后这应该有效:

foreach (var item in items)
{
    context.Attach(item);
    ... // now your item is attached to a live context again, and it
        // can hit the database
}

这假设你想懒得加载它 - 如果你想急切加载并避免第二次数据库命中,当你从数据库中检索项目时,你需要Include