2

LinqPad を使用して、NetFlix OData ソースにクエリを実行して Linq を学習しています。

(ところで、私は彼らがすでにSOにある同様の質問であることを知っています...助けにはなりませんでした)。

これは素晴らしいクエリです。

from x in Titles
//where x.Rating=="PG"
where x.Instant.Available==true
where x.AverageRating>=4.0
//where x.Rating.StartsWith("TV")
//where x.Genres.First (g => g.Name.Contains("Family") ) //(from y in Genres where y.Name.Contains("Family") select y)
//where x.Genres.First (g => g.Name=="")
//orderby x.Name
orderby x.AverageRating descending
//select x
//)
select new {x.Name, x.Rating, x.AverageRating, x.ShortSynopsis}

(すべてのコメントをご容赦ください...これは、私が実験中であり、さまざまなニーズに合わせてクエリを変更するという事実の証です)。

私が理解できないことが2つあります。

初め。最初の 10 件の結果のみを返したいとしましょう。

2番目(そして最も重要なこと)。ジャンルの部分文字列でフィルタリングしたい。各タイトルには Genres コレクションが含まれています。名前に特定の文字列 (「ファミリー」など) が含まれるジャンルのみを表示したい。ジャンル.name.に「firstFilter」と「secondFilter」が含まれるタイトルを使用して、さらに優れたフィルター処理を行います。

基本的に、ジャンルでフィルタリングしたいのですが、Title には独自の Genres コレクションが含まれているため、その方法がわかりません。コレクションの 1 つ以上のジャンルにあるタイトルのみを返す方法がわかりません。

ご協力いただきありがとうございます!

ps...Netflix OData ソースは Any 演算子をサポートしていないようです。

セス

4

3 に答える 3

4

最初の 10 件の結果を返すには、上記のコードを括弧で囲み、末尾に .Take(10) を配置します。

var foo = ( from x in Titles... ).Take(10);

現在、C# でクエリ構文を使用して取得する方法はありません。

ジャンル フィルターに関しては、klabranche が指摘しているように、oData は、通常の IEnumerable または IQueryable でローカルに使用できる同じ Linq コンストラクトの多くをサポートしていません。

klabranche のソリューションは、contains をサポートしていません。ただし、結果を取得するためにサーバーへの往復が 2 回行われます。(なぜこれが必要なのかについては、彼の答えに対する私のコメントを参照してください)

これは、サーバーへの往復を 1 回行ってデータを取得し、そのデータをローカルで処理する代替手段です。一部のクエリはローカルで実行されるため、string.Contains、"or" 句、およびその他の優れた機能を使用できます。

このアプローチの欠点は、クエリに答えるのに必要な量よりも多くのデータをネットワーク経由で取得することです。その一方で、理解しやすく、機能します。

「家族」と「子供」を組み合わせると、21 件の結果が返されます。

var oDataQuery = from x in Titles
                 where x.AverageRating >= 4
                    && x.Instant.Available==true       
                 orderby x.AverageRating descending
                 select new {x.Name, x.Rating, x.AverageRating, x.ShortSynopsis, x.Genres};

var localQuery = from o in oDataQuery.ToList()
                 where o.Genres.Any(g => g.Name.Contains("Family"))
                    && o.Genres.Any(g => g.Name.Contains("Children"))
                 select new {o.Name, o.Rating, o.AverageRating, o.ShortSynopsis };

localQuery.Dump();
于 2010-09-18T17:41:39.127 に答える
1

最初の10を取得するには:

(from x in Titles
where x.Instant.Available==true 
where x.AverageRating>=4.0 
orderby x.AverageRating descending 
select new {x.Name, x.Rating, x.AverageRating, x.ShortSynopsis}
).Take(10)

単一のジャンルでフィルタリングするには(必要なものではありません...):

from g in Genres
from t in g.Titles 
where g.Name == "Horror" 
where t.Instant.Available==true
where t.AverageRating >=4.0
orderby t.AverageRating descending 
select new {t.Name, t.Rating, t.AverageRating, t.ShortSynopsis}

ただし、複数のジャンルが必要でしたが、ODataはSelect Manyクエリをサポートしていません。そのため、containsが失敗するか、ジャンル名をORしようとします。

が多くを返すため、以下は失敗します...

var q1 = from g in Genres
from t in g.Titles 
where g.Name.Contains("Horror")
where t.Instant.Available==true
where t.AverageRating >=4.0
orderby t.AverageRating descending 
select new {t.Name, t.Rating, t.AverageRating, t.ShortSynopsis};

複数のジャンルでフィルタリングするには、ConcatまたはUnionクエリを使用できることがわかりました(LinqPadでは、式ではなくC#ステートメントに変更してください)。

var q1 = from g in Genres
from t in g.Titles 
where g.Name=="Horror"
where t.Instant.Available==true
where t.AverageRating >=4.0
orderby t.AverageRating descending 
select new {t.Name, t.Rating, t.AverageRating, t.ShortSynopsis};

var q2 = from g in Genres
from t in g.Titles 
where g.Name=="HBO"
where t.Instant.Available==true
where t.AverageRating >=4.0
orderby t.AverageRating descending 
select new {t.Name, t.Rating, t.AverageRating, t.ShortSynopsis};

var concat = q1.ToList().Concat(q2);
//var union = q1.Union(q2);

2つのクエリを結合すると、重複が削除されますが、これらは必要なものです。両方のジャンルのみの映画が必要であるという点で正しく理解している場合はどうでしょうか。

その場合、すべてのレコードを返すConcatを使用する必要があります。

これで、クエリに複数回含まれるレコードを検索するだけで、結果が得られます。

var results = from c in concat
group c by c.Name into grp
where grp.Count() > 1
select grp;
于 2010-09-18T19:56:52.687 に答える
1

OData と Netflix API は、Take() メソッドと Contains() メソッドをサポートしています。

from t in Titles
where t.Name.Contains("Matrix")
select t

(from t in Titles
where t.Name.Contains("Matrix")
select t).Take(10)
于 2010-09-18T17:42:22.020 に答える