c# – Linq查询blob列表,内存使用情况

你好开发者,

我正在尝试使用Linq查询改进在Oracle数据库中以BLOB格式存储的XML对象列表的导出.

可悲的是,其中一个BLOB非常大,当我读它时内存使用量增长到2 GB.我的fileSet对象是一个IQueryable< myRecord>宾语.
我试过了

foreach (var file in fileSet){...}

var files = fileSet.ToList(); //This time the list is causing the memory load.
foreach(file in files){...}

var e = fileSet.AsEnumerable().GetEnumerator();
while(e.MoveNext()){...}

但每当我打到列表中的大记录时,ram就会被过度使用.
为了创建导出,我正在寻找使用Buffer.BlockCopy的一些代码,但是由于内存过量充电,如果你有一些想法如何减少内存使用或延迟加载每个blob,那么就没有必要在这个方向上进一步发展: (

最佳答案 有几种解决方案:

1)将AsNoTracking()添加到您的查询中.

fileSet.AsNoTracking() or fileSet.AsNoTracking().Where(...) 

AsNoTracking()帮助垃圾收集器释放记录,因为记录不会缓存在数据库上下文中.但是,如您所知,它不会立即起作用,您仍然可能会消耗本地内存.

2)您可以创建一个单独的记录定义,该记录不包含blob字段并通过它获取文件列表或使用select表达式它也可能有帮助但你应该检查它是如何转换为sql的

fileSet.AsNoTracking().Select(x=>new { x.Id, x.Name })

然后处理每条记录,你将明确得到一个blob

var myblob = model.Database
    .SqlQuery<string>("select myblob from mytable where id=@id", 
         new SqlParameter("@id", System.Data.SqlDbType.Int) { Value = myId })
    .FirstOrDefault();

要么

var myBlob = fileSet
       .AsNoTracking()
       .Select(x=>new { x.Blob )
       .FirstOrDefault(x=>x.ConfigId=myId);
点赞