C# blob的Linq查询列表,内存使用情况
各位开发者好 我正在尝试使用Linq查询改进以BLOB格式存储在Oracle数据库中的XML对象列表的导出 遗憾的是,其中一个BLOB相当大,当我阅读它时,内存使用量增长到2GB。我的C# blob的Linq查询列表,内存使用情况,c#,linq,memory,blob,C#,Linq,Memory,Blob,各位开发者好 我正在尝试使用Linq查询改进以BLOB格式存储在Oracle数据库中的XML对象列表的导出 遗憾的是,其中一个BLOB相当大,当我阅读它时,内存使用量增长到2GB。我的fileSet对象是一个IQueryable对象。 我试过了 及 及 但每次我在名单上创下大记录时,内存都被过度使用了。 对于导出的创建,我正在使用Buffer.BlockCopy查找一些代码,但是由于内存过度充电,如果您知道如何减少内存使用或延迟加载每个blob,那么就没有必要再进一步了:(有几种解决方案: 1)
fileSet
对象是一个IQueryable
对象。
我试过了
及
及
但每次我在名单上创下大记录时,内存都被过度使用了。
对于导出的创建,我正在使用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();
最后,因为我无法使用linq在内存中存储一些内容,所以在使用linq获得文件ID后,我使用了
OracleCommand
来流式处理xml文件
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var blob = reader.GetOracleLob(0);
var buffer = new byte[128];
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write))
{
blob.CopyTo(fs);
}
}
}
您是否需要在处理过程中加载blob,或者只是因为文件集的记录定义中有此blob字段才加载blob?@SergeyL我需要blob,此软件正在加载这些blob并将其导出到xls文件中,基本上是xml inside.Tanks,请回答。因为我仍然使用EF4.0,我没有访问
AsNoTracking()
的权限,所以我尝试了fileSet.SetMergeOption(MergeOption.NoTracking)代码>但它没有改变结果,在加载带有大blob的对象后仍然会占用大量内存。但我会继续搜索这方面的信息,如果我的经理同意的话,我可能会更新我的EF^^
fileSet.AsNoTracking().Select(x=>new { x.Id, x.Name })
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);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var blob = reader.GetOracleLob(0);
var buffer = new byte[128];
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write))
{
blob.CopyTo(fs);
}
}
}