5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EF Core 拡張メソッド実装テンプレ集

Posted at

はじめに

この記事は、
EF Core で安全に使える拡張メソッドの「型」だけを集めたテンプレ集です。

  • どこまでなら SQL に変換されるか
  • どこからメモリ処理になるか

を常に意識した形になっています。

※ 本記事は、EF Core を業務で使い始めた〜使い慣れてきた方向けです。


基本ルール(先に結論)

  • 戻り値は IQueryable を維持する
  • 中で ToList() / AsEnumerable() を呼ばない
  • Where は Expression or IQueryable 合成
  • Select は DB でできる射影まで

① Where 用テンプレ(条件追加)

最も基本形

public static IQueryable<User> WhereActive(
    this IQueryable<User> query)
{
    return query.Where(u => u.IsActive);
}

db.Users
  .WhereActive()
  .ToList();

条件付き Where(if 文で分岐)

public static IQueryable<User> WhereActiveIf(
    this IQueryable<User> query,
    bool onlyActive)
{
    if (!onlyActive) { return query; }

    return query.Where(u => u.IsActive);
}

👉 条件を外から渡しても SQL は 1 本


② Where(Expression 版・再利用向け)

public static class UserPredicates
{
    public static Expression<Func<User, bool>> IsAdult()
        => u => u.Age >= 20;
}

db.Users
  .Where(UserPredicates.IsAdult())
  .ToList();

👉 EF Core が読める形


③ Select(射影)用テンプレ

DTO / Row への変換

public static IQueryable<UserRow> ToRow(
    this IQueryable<User> query)
{
    return query.Select(u => new UserRow
    {
        Id = u.Id,
        Name = u.Name,
        CreatedAt = u.CreatedAt
    });
}

db.Users
  .WhereActive()
  .ToRow()
  .ToList();

❌ NG:Select 内でメソッド呼び出し

// NG
.Select(u => new UserRow
{
    DisplayName = FormatName(u.Name)
});

👉 SQL に変換できない


④ OrderBy 用テンプレ

public static IQueryable<User> OrderByNewest(
    this IQueryable<User> query)
{
    return query.OrderByDescending(u => u.CreatedAt);
}

db.Users
  .WhereActive()
  .OrderByNewest()
  .ToList();

⑤ ページング用テンプレ

public static IQueryable<T> Page<T>(
    this IQueryable<T> query,
    int page,
    int pageSize)
{
    return query
        .Skip((page - 1) * pageSize)
        .Take(pageSize);
}

db.Users
  .WhereActive()
  .OrderByNewest()
  .Page(1, 20)
  .ToList();

⑥ ❌ やってはいけない拡張メソッド例

中で ToList

public static IEnumerable<User> Active(
    this IQueryable<User> query)
{
    return query.Where(u => u.IsActive).ToList();
}
  • クエリ合成できない
  • 呼び出し側が DB / メモリを判断できない

実装者向け最終チェック

  • 戻り値は IQueryable のままか?
  • この処理、SQL で書けるか?
  • メモリ処理は ToList() 以降に閉じているか?

まとめ

良い拡張メソッドは
「LINQ を短くする」のではなく
「安全な形に固定する」ためにある

このテンプレをベースにすると、
EF Core の拡張メソッドはかなり事故りにくくなります。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?