読者です 読者をやめる 読者になる 読者になる

しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

LightSpeed ORM で Bulk Update と Bulk Delete を試してみる

Entity Framework や LINQ to SQL を使っている皆が不満に思っているのが、更新と削除を 1 エンティティ毎にしか行えないことだと思います。例を挙げると Entity Framework では以下のようなコードを書く必要があります。

複数エンティティの更新

// 10000 円以上の商品は送料無料にする
var productList = context.Products.Where(p => p.Price > 10000).ToList();

foreach (var product in productList)
{
    // 送料を 0 円にする
    product.ShippingCost = 0;
}

// 変更を保存
context.SaveChanges();

複数エンティティの削除

// 在庫がない商品を削除する
var productList = context.Products.Where(p => p.Stock == 0).ToList();

foreach (var product in productList)
{
    // 取得したエンティティを削除
    context.Products.Remove(product);
}

// 変更を保存
context.SaveChanges();

更新や削除はエンティティを取得してから行う必要があるのでこうなってしまう訳ですね。SQL 自体には UPDATE と DELETE で一括更新が出来るのに、ORM が付いてこれていなくて残念な感じです。

ちなみに Entity Framework では SqlCommand メソッドが Database に用意されているので、これを直接叩くと一括で更新と削除はできます。

// 一括で削除
context.Database.SqlCommand("UPDATE [dbo].[Products] SET ShippingCost = 0 WHERE Price > 10000");

// 一括で削除
context.Database.SqlCommand("DELETE FROM [dbo].[Products] WHERE Stock = 0");

いやいやいや、これだと超重量級の Entity Framework を使ってる意味がないじゃないか。ということで LightSpeed ORM を使って、SQL 手書きなんてせずにもっと美しく Bulk Update と Bulk Delete を行いたいと思います。

Bulk Updates and Deletes - Mindscape

しっかりと対応しているところがありがたいですね。という訳でさっきと同じ処理を LightSpeed ORM を使って書き直してみます。

複数エンティティの更新

// 条件となるクエリを組み立てる
var query = new Query(typeof(Product), Entity.Attribute("Price") > 10000);

// 引数でクエリと更新する値を渡す
unitOfWork.Update(query, new { ShippingCost = 0 });

// 変更を保存
unitOfWork.SaveChanges();

複数エンティティの削除

// 条件となるクエリを組み立てる
var query = new Query(typeof(Product), Entity.Attribute("Stock") = 0);

// 引数で削除するクエリを渡す
unitOfWork.Remove(query);

// 変更を保存
unitOfWork.SaveChanges();

LightSpeed ORM では Query というクラスで WHERE 句を作れるので、あとは Update や Remove メソッドに渡すだけで一括で更新が行えます。

これだけの為にストアド作らなくてもいいんです!!