1

パラメータ化された Lambda クエリをいくつか作成します

        //Method 1:
        Func<SalesOrderLineEntity, bool> func01 = (o => o.SOLNumber == "123456");
        var q01 = _context.SalesOrderLineEntities.Where(func01).ToList();
        //Got the result, but SQLServer Read All Records to memory before "where"

        //Method 2:
        Expression<Func<SalesOrderLineEntity, bool>> exp02 = (o => o.SOLNumber == "123456");
        var q02 = _context.SalesOrderLineEntities.Where(exp02).ToList();
        //Got the result,Exec "Where" in SQLServer

        //Method 3:
        Expression<Func<SalesOrderLineEntity, bool>> exp03 = (o => func01(o));
        var q03 = _context.SalesOrderLineEntities.Where(exp03.Compile()).ToList();
        //Same to Method 1,because Compile() result is Func<SalesOrderLineEntity, bool>

        //Method 4:
        var q04 = _context.SalesOrderLineEntities.Where(exp03).ToList();
        //Error:The LINQ expression node type 'Invoke' is not supported in LINQ to Entities

方法 1 および 3:効率が非常に低い 方法 4 : エラー

方法 2 : Lambda を使用して式を作成する必要があります。if,else を多用するので難しいと思いますが、簡単に関数を作ることができます。それを行う正しい方法は何ですか?

4

2 に答える 2

1

バリエーション

方法 1Func : EFは、句にa を渡すため、DB からすべてのレコードを読み取りますがWhere、これは適切な候補ではありません: EF は、必要な情報をそこから抽出してクエリを作成することはできません。コレクション。

方法 2 : EF は .xml に基づいて実際のクエリを構築するため、これは EF クエリを実行する正しい方法ですExpression tree。書くと方法1と同じに見えるかもしれません.Whereが、これは違います。

IQueryable拡張メソッドはExpression treesを使用しているため、実行時にその情報を評価できます (または EF できます)。

方法 3 : 式をコンパイルするため、これは本質的に方法 1 と同じです。これは、それらを使用する際の重要な違いです。式には、実際の操作を構築するための情報が含まれていますが、それは操作自体ではありません。前にコンパイルする必要があります (または、たとえば、それらに基づいて SQL クエリを作成できます。これが EF のしくみです)。

方法 4 : EF はfunc01()呼び出しを SQL 関数に変換できません。同等の SQL 操作が必要なため、どのような種類のコードも変換できません。一般的な方法を使用してみると、同じ結果が得られます。これは Func に関するものではありません。

そこで何が起こるの?

根底にあるプロセスを単純化すれば、上記の答えはより明確になるかもしれません。

//Method 2:
Expression<Func<SalesOrderLineEntity, bool>> exp02 = (o => o.SOLNumber == "123456");
var q02 = _context.SalesOrderLineEntities.Where(exp02).ToList();
//Got the result,Exec "Where" in SQLServer

EF は (式を介して) 以下を読み取ることができます。

  • ユーザーがフィルタリングしたいWhere
  • これがその表現です。情報を取得しましょう。
  • まあ、それは必要SalesOrderLineEntityであり、私はそのタイプのマッピングを持っています
  • 式は、プロパティSOLNumberが「123456」と等しくなければならないことを示しています
  • わかりました、私はのためのマッピングを持っているSOLNumberので、それは良いです
  • 等号演算子を同等の SQL 演算子に変換できます
  • すべて問題ないので、SQL クエリを作成できます

もちろん、Funcたとえばオブジェクトにはこれらの情報が含まれていないため、これを行うことはできません。

于 2013-01-22T13:35:07.423 に答える