EF:按ID更新字段的最佳/最快方式

时间:2017-02-07 08:50:14

标签: c# entity-framework

目前,数据库记录从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查询)?

1 个答案:

答案 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;
 }