演習 - 統合言語クエリを使用して項目を列挙する (LINQ)

完了

このアプリケーションはすべての要件を既に満たしていますが、変更を加えることができる部分がもう 1 つ残っています。 C# 開発者は、統合言語クエリ (LINQ) 構文を使って、データのコレクションのクエリを実行します。 Azure Cosmos DB for NoSQL 用 .NET SDK には、LINQ メソッド構文を使用してクエリを構築するための組み込みメカニズムが付属しています。

ここでの重要な要件は次の 2 つです。

  1. LINQ 構文を使って新しいクエリを作成する
  2. クエリをフィード反復子に変換して結果を取得する

LINQ 式を使ってクエリを実行されているデータを示すアイコンの図。

この演習を完了すると、クエリで LINQ 構文が使われるようになり、先々開発者がアプリケーションを保守しやすくなります。

LINQ 式を使用してクエリを実行する

あなたのチームは、カテゴリに関係なくコンテナー内のすべての "製品" を返す独自のクエリを必要としています。 type プロパティを使って、カテゴリ項目を個別の製品項目から分離したことを思い出してください。 ここでは、LINQ メソッド構文を使ってクロスパーティション クエリを作成します。

ヒント

複数のカテゴリにわたってクエリを実行するため、クエリはクロスパーティションになります。 このクエリでは、1 つの論理パーティション キー値をスコープとするクエリより多くの RU を使う可能性があります。

  1. Program.cs ファイルを最後に開きます。

  2. GetItemLinqQueryable メソッドを使って、新しい LINQ クエリを作成します。

    IOrderedQueryable<Product> queryable = container.GetItemLinqQueryable<Product>();
    
  3. Where メソッドと OrderBy メソッドを使って LINQ 式を作成し、新しい変数に式を格納します。

    var matches = queryable
        .Where(p => p.Type == nameof(Product))
        .Where(p => !p.Archived)
        .OrderBy(p => p.Price);
    
  4. IOrderedQueryable<>.ToFeedIterator メソッドを使って、LINQ 式からフィード反復子を取得します。

    using FeedIterator<Product> linqFeed = matches.ToFeedIterator();
    
  5. コンソールにメッセージを出力します。

    Console.WriteLine($"[Start LINQ query]");
    
  6. Program.cs ファイルを保存します。

LINQ クエリの結果をページ分割する

複数の論理パーティションにわたってクエリを実行するため、1 つの論理パーティションに一致する結果がない場合でも、すべての結果が返されるようにする必要があります。 たとえば、helmets カテゴリには一致する製品がありません。 可能なすべてのページを返さないとすると、helmets カテゴリの結果が空のページになった時点で、アプリケーションが誤って停止するおそれがあります。 ここでは、C# の while ループと foreach ループをもう一度使用し、"すべての" 結果ページを反復処理します。 このコードは、前にフィード反復子を使用した方法と同じようになるはずです。

  1. Program.cs で、フィード反復子にそれ以上ページがなくなるまで処理を繰り返す while ループを作成します。

    while (linqFeed.HasMoreResults)
    {    
    }
    
  2. while ループ内で、結果の新しいページを取得します。

    FeedResponse<Product> page = await linqFeed.ReadNextAsync();
    
  3. while ループ内で、現在のページの要求使用量を出力します。

    Console.WriteLine($"[Page RU charge]:\t{page.RequestCharge}");
    
  4. while ループ内に、ページの項目を反復処理する新しい foreach ループを作成します。

    foreach (Product item in page)
    {
    }
    
  5. foreach ループ内で、個々の項目をコンソールに表示します。

    Console.WriteLine($"[Returned item]:\t{item}");
    
  6. Program.cs ファイルを保存します。

作業を確認

これで、アプリは、LINQ を使って、開発者チームがネイティブに理解するクロスパーティション クエリを作成するようになりました。 ここで、アプリケーションを最後に 1 回実行し、すべてのクエリから期待した結果が返されることを確認します。

  1. ターミナルで .NET アプリケーションを実行します。

    dotnet run
    
  2. アプリケーションを実行した出力を確認します。 出力は、次の例と一致しているはずです。

    [Start LINQ query]
    [Page RU charge]:       3
    [Returned item]:        Product { Id = 6e3b7275-57d4-4418-914d-14d1baca0979, CategoryId = gear-camp-tents, Type = Product, Name = Nimbolo Tent, Price = 330, Archived = False, Quantity = 35 }
    [Returned item]:        Product { Id = e8dddee4-9f43-4d15-9b08-0d7f36adcac8, CategoryId = gear-camp-tents, Type = Product, Name = Cirroa Tent, Price = 490, Archived = False, Quantity = 15 }
    [Returned item]:        Product { Id = e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa, CategoryId = gear-camp-tents, Type = Product, Name = Kuloar Tent, Price = 530, Archived = False, Quantity = 8 }
    

    ヒント

    この出力例で示されている RU は、実際の出力と異なる場合があります。