2012-03-14 8 views
5

現在、LINQの基本を理解しようとしています。私はLINQPadを使用してNetflix ODataソースを照会しています。LINQラムダクエリ 'select'がoDataと連携しない

出典:http://odata.netflix.com/v2/Catalog/

ラムダクエリを使用したとき、私は単一のプロパティを選択するように見えることはできません - 理解クエリは完璧に動作します。 Netflix oDataソースでlambdasを使用してより複雑なクエリを実行するコードスニペットが見つかりました。これはエンティティの1つのプロパティを返すためにうまくいくようです。

// works fine 
var compQuery = from t in Titles 
       where t.ReleaseYear == 2007 
       select new { t.Name }; 
compQuery.Dump(); 



// fails: "Can only specify query options (orderby, where, take, skip) after last navigation." 
var lambdaQuery = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(t => t.Name); 

lambdaQuery.Dump(); 


// works fine - found on SO. 
var lambdaQuery2 = People 
    .Expand("TitlesActedIn") 
    .Where(p => p.Name == "George Lucas") 
    .First() 
    .TitlesActedIn.Select(t => t.ShortName);    

lambdaQuery2.Dump(); 

誰もが1つのプロパティを返すように求められたときの基本的なラムダクエリが失敗する理由としていくつかの光を当てますか?

答えて

4

それはあなたの最初のものと実際に等価であるものであるthis-試してみてください。

// fails: "Can only specify query options (orderby, where, take, skip) after last navigation." 
var lambdaQuery = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(t => new { t.Name }); 

lambdaQuery.Dump(); 
+0

ああ、私は今それを試して、それは動作します! - 私が理解していないのは、他のラムダクエリ(人)が私に投影用の匿名型を作成する必要がないということです。 – Dal

+0

結果を具体化する '.First()'を呼び出すので、レコード全体を吸い取り、クライアントのメモリ内のプロパティを選択します。 –

+0

匿名タイプを使用する必要がある理由について説明しますか? ありがとう –

12

のODataは、プロパティに投影するためのサポートを持っていない - あなたはこのかかわらず、回避することができます。

var lambdaQuery = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(x=> new { x.Name }) 
      .AsEnumerable() 
      .Select(t => t.Name); 

AsEnumerable()を使用すると、投影がうまく動作する(ODataクエリではなく)Linq-to-Objectsコンテキストでクエリの最後の部分が実行されます。与えられた答えを使用して

+0

ありがとうございます、私はここでAsEnumerableに関するいくつかの情報を見つけました - http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/d427cbf6-4d8a-42ee-9799-d5ca79e581dc – Dal

+0

私は仕事からこれをテストすることができればいいのに(Netflixはここでブロックされている)、実際に最初に必要なのは?ここで少し冗長に思えます。 –

+0

@JeffMercado:Odata(と上のコメントのリンク)によると、odata投影法はエンティティ自体を送信しますが、不要なプロパティは除外します。したがって、パフォーマンスを上げるためにはこれを残してワイヤーを通過するデータ – BrokenGlass

0

は、私はいくつかのテストを実行し、実行時間に関するいくつかの興味深いことを発見した:

// Avg Execution Time: 5 seconds 
var query1 = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .Select(t => new {t.Name});  
query1.Dump(); 


// Avg Execution Time: 15 seconds 
var query2 = Titles 
      .Where(t => t.ReleaseYear == 2007) 
      .AsEnumerable() 
      .Select(t => t.Name);  
query2.Dump(); 

だから私は、右のクエリ1で、唯一の「名前」プロパティが返されていることを考えるにしています?クエリ2では、 'AsEnumerable()'メソッドはすべてのプロパティ値、つまり実行時間が長いエンティティを戻していますか?

+0

はい、照会されたデータはquery2の方がはるかに大きくなります。また、エンティティ全体を照会しているため、コンテキストによって変更追跡されます。 – springy76

関連する問題