目前,数据库记录从get加载到简化模型中,该模型还存储了ID密钥。经过一些计算后,需要更新原始记录的一个或多个字段。
模型非常大(很多字符串),并且入门数可能是>每桌100.000个条目。因此将它们加载到内存中会导致OutOfMemoryException。
class Model // Database-Table
{
public Int Id { get; set; }
public int Field { get; set; }
}
class SimpleModel
{
int Id;
int Field;
}
void Update( SimpleModel[] simpleModels )
{
using( var ctx = new DbContext() )
{
foreach( var simpleModel in simpleModels )
{
var entry = ctx.ModelTable
.Where( x => x.Id == simpleModel.Id )
.FirstOrDefault();
if( entry == null )
continue;
ctx.ModelTable.Attach( entry );
entry.Field = simpleModel.Field;
}
if( ctx.ChangeTracker.HasChanges() )
ctx.SaveChanges();
}
}
然而,这非常缓慢。有没有办法加快这一点,使用EntityFramework(没有直接的字符串-sql查询)?
答案 0 :(得分:3)
每次使用FirstOrDefault()
时,都会运行新的数据库查询。您可以在一个查询中加载所有实体:
var ids = simpleModels.Select(sm => sm.Id);
var entries = ctx.ModelTable.Where(m => ids.Contains(m.Id)).ToList();
// or
var entriesById = ctx.ModelTable.Where(m => ids.Contains(m.Id)).ToDictionary(x => x.Id);
然后,您可以在内存中处理已加载的条目,而无需其他数据库查询。 E.g。
foreach( var simpleModel in simpleModels )
{
Model entry;
if (!entriesById.TryGetValue(simpleModel.Id, out entry))
continue;
entry.Field = simpleModel.Field;
}