【发布时间】:2012-08-12 07:24:33
【问题描述】:
假设,我们有一个表,其中包含一些大的 text 字段,其中包含 jpg 文件的二进制数据。任务是从磁盘上的数据库中获取这些文件。所以,起初我决定做以下事情:
MyDataContext dc = new MyDataContext();
foreach(ImageTable t in dc.ImageTable.OrderBy(i=>i.Id))
{
using (StreamWriter writer = new StreamWriter(new FileStream(string.Concat(t.Name,".jpg"), FileMode.CreateNew), Encoding.GetEncoding(1251)))
{
writer.Write(t.Data);
writer.Close();
}
}
但是当表格有大约 20000 行时,我很快就收到了OutOfMemoryException。
最后,为了避免将所有行加载到一个数据上下文中,我做了以下操作:
MyDataContext dc = new MyDataContext();
foreach(int id in dc.ImageTable.OrderBy(i=>i.Id).Select(i=>i.Id))
{
using (MyDataContext _dc = new MyDataContext())
{
ImageTable t = _dc.ImageTable.FirstOrDefault(i => i.Id == id);
using (StreamWriter writer = new StreamWriter(new FileStream(string.Concat(t.Name,".jpg"), FileMode.CreateNew), Encoding.GetEncoding(1251)))
{
writer.Write(t.Data);
writer.Close();
}
}
}
所以每一行都由一个单独的数据上下文加载...没有内存问题! 但这肯定不是完成任务的最佳方法。
谁能给点建议?
【问题讨论】:
-
创建一个新的数据上下文是一个轻量级的操作,所以这不是什么大问题。话虽这么说,像支出者提到的那样关闭对象跟踪是正确的解决方案。
-
首先,你需要20000行数据干什么???其次,为什么将 jpgs 存储在数据库中? “你可以”这一事实并不意味着“你应该”。
-
我不在那里存储图片...一些公司软件会...我的任务是将它们从数据库中取出以导入其他系统...所以,显然所有的行必须导出到磁盘)
标签: c# linq linq-to-sql sql-server-2000 out-of-memory