2

比如说,我们有一个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();
    }
}

但是一旦表格有大约 20,000 行,我很快就得到了一个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();
           }
      }
}    

所以每一行都由一个单独的数据上下文加载......没有内存问题!但这肯定不是完成任务的最佳方法。

有人可以提出一些建议吗?

4

2 回答 2

3

您可以尝试关闭对象跟踪

_dc.ObjectTrackingEnabled = false;
于 2012-08-15T23:40:50.143 回答
2
  1. 如果它已经有效:解决内存问题,性能满足您的应用程序需求,这是一个很好的解决方案

  2. 如果您仍然对结果不满意,您可以考虑离开linq to sql并查看raw SQL使用SqlDataReaderreadonly只向前游标,以获得最大的读取操作效率。

希望这可以帮助。

于 2012-08-15T23:40:56.990 回答