0

我有这种创建方法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;为什么又会出现这个错误?

4

3 回答 3

3

IEnumerable<T>你传入的那个toDataTable<T>()还没有实现。的上下文items已经被释放。您忘记了ToList()调用代码中的 a。

于 2013-08-28T19:54:40.320 回答
1

如果也items起源于EntityFramework,那么它可能是罪魁祸首——它的上下文可能已经关闭。

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

于 2013-08-28T19:54:53.077 回答
1

我假设该items集合包含来自 EF 的实体。这些项目最初属于 an 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
}

这是假设您想延迟加载它 - 如果您想急切地加载并避免第二次数据库命中,您首先需要在从数据库中检索项目时包含它。

于 2013-08-28T19:54:53.873 回答