你好开发者,
我正在尝试使用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);