我有这种创建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
;为什么会再次出现这个错误?
答案 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。