说,我们有一个表格,其中包含一些包含jpg文件的大型text
字段的二进制数据。任务是从磁盘上的数据库中获取这些文件。所以,起初我决定做以下事情:
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();
}
}
但是一旦桌子有大约2万行,我有一段时间得到OutOfMemoryException
。
最后,为了避免将所有行加载到一个datacontext中,我执行了以下操作:
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();
}
}
}
所以每一行都由一个单独的datacontext加载......没有内存问题! 但当然,这不是完成任务的最佳方法。
有人可以提出建议吗?
答案 0 :(得分:3)
您可以尝试关闭object tracking:
_dc.ObjectTrackingEnabled = false;
答案 1 :(得分:2)
如果它已经有效:解决内存问题,性能符合您的应用需求,这是一个很好的解决方案。
如果您对结果仍然不满意,可能考虑离开linq to sql
并查看raw SQL
使用SqlDataReader < em> readonly ,仅转发光标,以在读取操作中获得最大效率。
希望这有帮助。