【Entity Framework Core】レコード更新と性能比較

【Entity Framework Core】レコード更新と性能比較

Entity Framework Core によるレコード更新方法と性能比較結果を記載します。

エンティティ更新

エンティティを取得して値を更新します。そのあとに、SaveChangeメソッドを実行することでレコードを更新します。

using (var context = new Context())
{
    foreach (var product in context.Products.Where(p => p.Price == 1000).ToList())
    {
        product.CategoryId = 50;    // 値を更新
    }
    context.SaveChanges();
}

Update

Updateメソッドに値を更新した単一エンティティを設定します。そのあと、SaveChangeメソッドを実行することでレコードを更新します。

using (var context = new Context())
{
    var product = context.Products.Single(p => p.Id == 1);
    product.Price = 1000;    // 値を更新

    context.Products.Update(product);
    context.SaveChanges();
}

UpdateRange

UpdateRangeメソッドに値を更新した複数エンティティを設定します。そのあと、SaveChangeメソッドを実行することでレコードを更新します。

using (var context = new Context())
{
    var products = new List<Product>();
    foreach (var product in context.Products.Where(p => p.Price == 1000).ToList())
    {
        product.CategoryId = 50;    // 値を更新
        products.Add(product);
    }

    context.Products.UpdateRange(products);
    context.SaveChanges();
}

Attach

Attachメソッドに値を更新した単一エンティティをアタッチします。そのあと、更新状態にしてSaveChangeメソッドを実行することでレコードを更新します。

using (var context = new Context())
{
    var product = context.Products.Single(p => p.Id == 1);
    product.Price = 1000;    // 値を更新
    context.Products.Attach(product);
    context.Entry(product).State = EntityState.Modified;
    context.SaveChanges();
}

AttachRange

AttachRangeメソッドで値を更新した複数エンティティをアタッチします。そのあと、更新状態にしてSaveChangeメソッドを実行することでレコードを更新します

using (var context = new Context())
{
    var products = new List<Product>();
    foreach (var product in context.Products.Where(p => p.Price == 1000).ToList())
    {
        product.CategoryId = 50;    // 値を更新
        products.Add(product);
    }

    context.Products.AttachRange(products);
    foreach (var product in products)
    {
        context.Entry(product).State = EntityState.Modified;
    }
    context.SaveChanges();
}

CurrentValue

Entryメソッドを使用して単一エンティティを取得します。
そのあと、Propertyメソッドを使用して変更するプロパティを指定し、CurrentValueプロパティで値を更新します。
最後にSaveChangeメソッドを実行することでレコードを更新します。

using (var context = new Context())
{
    foreach (var product in context.Products.Where(p => p.Price == 1000).ToList())
    {
        context.Entry(product).Property(c => c.CategoryId).CurrentValue = 50;    // 値を更新
    }
    context.SaveChanges();
}

Property

ExecuteUpdateメソッドを実行してレコードを更新します。SaveChangeメソッドは不要です。
※ExecuteUpdateメソッドはEFCore7.0から使用可能です。

using (var context = new Context())
{
    context.Products.Where(p => p.Price > 1000)
        .ExecuteUpdate(s => s.SetProperty(c => c.CategoryId, c => 50));    // 値を更新
}

性能比較

レコード更新方法ごとに性能測定した結果を記載します。
  • 計測環境
  • OS:Windows10(64-bit) RAM:16.0GB CPU:Core i7
    .Net7
    Entity Framework Core Version 7.0.3
    Microsoft SQL Server 2022 Developer Edition (64-bit)

  • 処理内容
  • 100万件のレコードを更新します。

  • 計測結果
  • 5回計測した結果の中央値を記載しています。
計測メソッド 処理時間(秒)
エンティティ更新 96.909
Update 91.781
UpdateRange 90.626
Attach 95.283
AttachRange 96.176
CurrentValue 97.021
ExecuteUpdate 03.581

ExecuteUpdateが他のメソッドより圧倒的に早い結果となりました。
ExecuteUpdateを除くとUpdateRangeが一番早い結果となりましたが、他のメソッドとそれほど性能差は見られませんでした。
Next Post Previous Post