LINQ to Entities サポート非対象の LINQ メソッド と メソッドチェーン中での値の変換

LINQ to Entities サポート非対象の LINQ メソッド http://msdn.microsoft.com/ja-jp/library/bb738550.aspx で気になったところ:

  • LINQ記述時に独自のIComparer や IEquality を使うような比較ができない
  • Aggregate による即時実行ができない

(午後に注記: 以下の ToString による型変換の件は Queryable.Cast を使えばいけるかもなので、後で検証する http://yyamasak.wordpress.com/2009/06/04/linq-to-entities-sqliteでcastexpression-as-type/)

最も問題になったのは、ToString() などを利用して、値を変換した集合を作り出したい時に、直接できなかったこと。 “System.String ToString()’ は LINQ to Entities では認識されないため、ストア式に変換できません。” というようなエラーになる。(参考 : http://www.moonmile.net/blog/archives/1695)

http://stackoverflow.com/questions/7298535/linq-to-entities-tostring-none-of-the-proposed-solutions-work にある解決例:

return new DataAccess()
    .Categories
    .OrderBy(c => c.Description)
    .ToList()
    .Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Description
        });

メソッドチェーン中で ToList() を利用し、ToString を LINQ to Objects の中で実行させて解決している。

このような制限が発生するのは、LINQ to Entities の表現がSQL Server 側で実施され、必要なデータだけを SQL Server から取得するため。だからこそ SQL 上のインデックスを有効に利用できるわけで、 SQL Server の CLR 関数と連携する未来を夢見ることにしよう。

CLR メソッドと正規関数とのマッピング とか カスタム データベース関数を呼び出す方法 とかあるやん。作ってれば当然欲しくなるものは、ちゃんと用意されているのですね。しかし、接続先をSQLから AzureTable に切り替えるかもしれない場合はやっぱり使えないので、安易な利用は禁物。正規関数 であれば「すべてのデータ プロバイダーがサポートし、あらゆるクエリ テクノロジで使用されている」なのだが、正規関数の中に型変換は存在しない。

# このことに気付いたのは ReSharper が賢すぎてループを LINQ に書き換えようとするため。LINQへの書き換えをそのまま実行しようとするとエラーになる。値の変換を見極めて、適宜自分で ToList() を挟むという作業を行うことになった。

# 正規関数 にある関数のラインナップを見てたら、 JScript の時に出来そうで出来なかった記憶を思い出してしまった。あの時もWindowsスクリプトファイル(.wsf)中に JScript と VBScript 混在させて足りない部分を何とかしていた。

LINQ to Entities サポート非対象の LINQ メソッド と メソッドチェーン中での値の変換」への1件のフィードバック

  1. .NET Clips より:

    LINQ to Entities サポート非対象の LINQ メソッド と メソッドチェーン中での値の変換 « Mimori’s Algorithms Press…

    素敵なエントリーの登録ありがとうございます – .NET Clipsからのトラックバック…

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。