教學課程:透過 Azure Cosmos DB for NoSQL 開發 ASP.NET Web 應用程式
適用於:NoSQL
適用於 .NET 的 Azure SDK 可讓您使用 C# 中的 LINQ 或 SQL 查詢字串,查詢 API for NoSQL 容器中的資料。 本教學課程將逐步解說如何更新使用預留位置資料的現有 ASP.NET Web 應用程式,以改為從 API 查詢。
在本教學課程中,您會了解如何:
- 使用 API for NoSQL 建立和填入資料庫和容器
- 從範本建立 ASP.NET Web 應用程式
- 使用適用於 .NET 的 Azure SDK 從 API for NoSQL 容器查詢資料
必要條件
- 現有的 Azure Cosmos DB for NoSQL 帳戶。
- 如果您有現有的 Azure 訂用帳戶,請建立新的帳戶。
- 沒有 Azure 訂用帳戶? 您可以免費試用 Azure Cosmos DB,不需要信用卡。
- Visual Studio Code
- .NET 6 (LTS) 或更新版本
- 體驗撰寫 C# 應用程式。
建立 API for NoSQL 資源
首先,您會在現有的 API for NoSQL 帳戶中建立資料庫和容器。 接著,您將使用 cosmicworks
dotnet 工具在此帳戶中填入資料。
在 Azure 入口網站中瀏覽至您現有的 API for NoSQL 帳戶。
在 [資源] 功能表中,選取 [金鑰]。
在 [金鑰] 頁面上,觀察並記錄 [主要連接字串] 字段的值。 在整個教學課程中,將會使用此值。
在 [資源] 功能表中,選取 [資料總管]。
在 [資料總管] 頁面上,選取命令列中的 [新增容器] 選項。
在 [新增容器] 對話方塊中,使用下列設定建立新的容器:
設定 值 資料庫識別碼 cosmicworks
資料庫輸送量類型 手動 資料庫輸送量數量 1000
容器識別碼 products
分割區索引鍵 /category/name
重要
在本教學課程中,我們會先將資料庫調整為 1,000 RU/秒的共用輸送量,以最大化數據遷移的效能。 資料移轉完成後,我們會縮小為已佈建輸送量的 400 RU/s。
選取 [確定] 以建立資料庫和容器。
開啟終端機來執行命令,以在容器中填入資料。
提示
您可以在此選擇性地使用 Azure Cloud Shell。
從 NuGet 安裝 dotnet 工具的
cosmicworks
v2。dotnet tool install --global cosmicworks --version 2.*
使用
cosmicworks
工具,使用您稍早在此實驗室中記錄的 [URI] 和 [主要金鑰]值,在 API for NoSQL 帳戶中填入範例產品資料。 這些記錄的值將分別用於endpoint
和key
參數。cosmicworks \ --number-of-products 1759 \ --number-of-employees 0 \ --disable-hierarchical-partition-keys \ --connection-string <nosql-connection-string>
觀察命令列工具的輸出。 它應該將1759個專案新增至容器。 包含的範例輸出會為了簡潔而截斷。
── Parsing connection string ──────────────────────────────────────────────────────────────── ╭─Connection string──────────────────────────────────────────────────────────────────────────╮ │ AccountEndpoint=https://<account-name>.documents.azure.com:443/;AccountKey=<account-key>; │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ── Populating data ────────────────────────────────────────────────────────────────────────── ╭─Products configuration─────────────────────────────────────────────────────────────────────╮ │ Database cosmicworks │ │ Container products │ │ Count 1,759 │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ... [SEED] 00000000-0000-0000-0000-000000005951 | Road-650 Black, 60 - Bikes [SEED] 00000000-0000-0000-0000-000000005950 | Mountain-100 Silver, 42 - Bikes [SEED] 00000000-0000-0000-0000-000000005949 | Men's Bib-Shorts, L - Clothing [SEED] 00000000-0000-0000-0000-000000005948 | ML Mountain Front Wheel - Components [SEED] 00000000-0000-0000-0000-000000005947 | Mountain-500 Silver, 42 - Bikes
返回您帳戶的 [資料總管] 頁面。
在 [資料] 區段中,展開
cosmicworks
資料庫節點,然後選取 [調整]。將輸送量從 1,000 減少到 400。
在命令列中,選取 [儲存]。
在 [資料] 區段中,展開並選取 [產品] 容器節點。
請在命令列中,選取 [新增 SQL 查詢]。
在查詢編輯器中,新增此 SQL 查詢字串。
SELECT p.sku, p.price FROM products p WHERE p.price < 2000 ORDER BY p.price DESC
選取 [執行查詢] 以執行查詢並觀察結果。
結果應該是容器中所有項目的編頁陣列,其
price
值小於 2,000(價格從最高到最低排序)。 為了簡潔起見,此處包含輸出的子集。[ { "sku": "BK-R79Y-48", "price": 1700.99 }, ... { "sku": "FR-M94B-46", "price": 1349.6 }, ...
以這個查詢取代查詢編輯器的內容,然後再次選取 [執行查詢] 以觀察結果。
SELECT p.name, p.category.name AS category, p.category.subCategory.name AS subcategory, p.tags FROM products p JOIN tag IN p.tags WHERE STRINGEQUALS(tag, "yellow", true)
結果應該是較小的項目陣列,該陣列已篩選為只包含至少有一個標籤且 name 值為
Tag-32
。 再度為了簡潔起見,此處包含輸出的子集。[ ... { "name": "HL Touring Frame - Yellow, 60", "category": "Components", "subcategory": "Touring Frames", "tags": [ "Components", "Touring Frames", "Yellow", "60" ] }, ... ]
建立 ASP.NET Web 應用程式
現在,您將使用範例專案範本建立新的 ASP.NET Web 應用程式。 接著,您將探索原始程式碼並執行範例以熟悉應用程式,再使用適用於 .NET 的 Azure SDK 提供 Azure Cosmos DB 連線能力。
重要
本教學課程會以透明方式從 NuGet 提取套件。 您可以使用 dotnet nuget list source
來驗證套件來源。 如果您沒有 NuGet 做為套件來源,請使用 dotnet nuget add source
將網站安裝為來源。
在空的目錄中開啟終端機。
從 NuGet 安裝
cosmicworks.template.web
專案範本套件。dotnet new install cosmicworks.template.web
使用新安裝的
dotnet new cosmosdbnosql-webapp
範本建立新的 Web 應用程式專案。dotnet new cosmosdbnosql-webapp
建置並執行 Web 應用程式專案。
dotnet run
觀察執行命令的輸出。 輸出應該包含應用程式執行所在的連接埠和 URL 清單。
... info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[14] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production ...
開啟新的瀏覽器,然後瀏覽至執行中的 Web 應用程式。 觀察執行中應用程式的全部三個頁面。
藉由終止執行中程序來停止執行中的應用程式。
提示
使用 Ctrl+C命令停止執行中的程序。或者,您可以關閉並重新開啟終端機。
使用目前專案資料夾作為工作區,開啟 Visual Studio Code。
提示
您可以在終端機中執行
code .
以開啟Visual Studio Code,並將工作目錄自動開啟為目前的工作區。瀏覽至並開啟 Services/ICosmosService.cs 檔案。 觀察
RetrieveActiveProductsAsync
和RetrieveAllProductsAsync
預設方法實作。 這些方法會建立第一次執行專案時要使用的產品靜態清單。 這裡提供其中一個方法的截斷範例。public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync() { await Task.Delay(1); return new List<Product>() { new Product(id: "baaa4d2d-5ebe-45fb-9a5c-d06876f408e0", category: new Category(name: "Components, Road Frames"), sku: "FR-R72R-60", name: """ML Road Frame - Red, 60""", description: """The product called "ML Road Frame - Red, 60".""", price: 594.83000000000004m), new Product(id: "bd43543e-024c-4cda-a852-e29202310214", category: new Category(name: "Components, Forks"), sku: "FK-5136", name: """ML Fork""", description: """The product called "ML Fork".""", price: 175.49000000000001m), ... }; }
瀏覽至並開啟 Services/ICosmosService.cs 檔案。 觀察 CosmosService 類別的目前實作。 這個類別會實作 ICosmosService 介面,但不會覆寫任何方法。 在此內容中,類別會使用預設介面實作,直到介面中提供實作的覆寫為止。
public class CosmosService : ICosmosService { }
最後,流覽至並開啟 Models/Product.cs 和 Models/Category.cs 檔案。 觀察每個檔案中定義的記錄類型。 本教學課程中將會在查詢中使用這些類型。
public record Product( string id, Category category, string sku, string name, string description, decimal price );
public record Category( string name );
使用 .NET SDK 查詢資料
接下來,您會將適用於 .NET 的 Azure SDK 新增至此範例專案,並使用程式庫從 API for NoSQL 容器查詢資料。
回到終端機,從 NuGet 新增
Microsoft.Azure.Cosmos
套件。dotnet add package Microsoft.Azure.Cosmos
組建專案。
dotnet build
回到 Visual Studio Code,再次瀏覽至 Services/CosmosService.cs 檔案。
為
Microsoft.Azure.Cosmos
和Microsoft.Azure.Cosmos.Linq
命名空間新增 using 指示詞。using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq;
在 CosmosService 類別中,新增名為
_client
且類型為CosmosClient
的新private readonly
成員。private readonly CosmosClient _client;
建立
CosmosService
類別的新空白建構函式。public CosmosService() { }
在建構函式中,建立
CosmosClient
類別的新執行個體,以您先前在實驗室中記錄的 [主要連接字串] 值傳入字串參數。 將這個新執行個體儲存在_client
成員中。public CosmosService() { _client = new CosmosClient( connectionString: "<primary-connection-string>" ); }
回到 CosmosService 類別,建立名為
container
且類型為Container
的新private
屬性。 設定 get 存取子以傳回cosmicworks
資料庫和products
容器。private Container container { get => _client.GetDatabase("cosmicworks").GetContainer("products"); }
建立名為
RetrieveAllProductsAsync
的新非同步方法,以傳回IEnumerable<Product>
。public async Task<IEnumerable<Product>> RetrieveAllProductsAsync() { }
針對後續步驟,在
RetrieveAllProductsAsync
方法中新增此程式碼。使用
GetItemLinqQueryable<>
泛型方法來取得IQueryable<>
類型的物件,您可將其用於建構語言整合式查詢 (LINQ)。 將該物件儲存在名為queryable
的變數中。var queryable = container.GetItemLinqQueryable<Product>();
使用
Where
和OrderByDescending
擴充方法建構 LINQ 查詢。 使用ToFeedIterator
擴充方法來建立迭代器,以從 Azure Cosmos DB 取得資料,並將迭代器儲存在名為feed
的變數中。 將此整個運算式包裝在 using 陳述式中,以便稍後處置迭代器。using FeedIterator<Product> feed = queryable .Where(p => p.price < 2000m) .OrderByDescending(p => p.price) .ToFeedIterator();
使用泛型
results
類型建立名為List<>
的新變數。List<Product> results = new();
建立會逐一查看的 while 迴圈,直到
feed
變數的HasMoreResults
屬性傳回 false 為止。 此迴圈可確保您迴圈處理伺服器端結果的所有頁面。while (feed.HasMoreResults) { }
在 while 迴圈內,以非同步方式呼叫
feed
變數的ReadNextAsync
方法,並將結果儲存在名為response
的變數中。while (feed.HasMoreResults) { var response = await feed.ReadNextAsync(); }
仍在 while 迴圈內,使用 foreach 迴圈來閱覽回應中的每個項目,並將其新增至
results
清單。while (feed.HasMoreResults) { var response = await feed.ReadNextAsync(); foreach (Product item in response) { results.Add(item); } }
傳回
results
清單作為RetrieveAllProductsAsync
方法的輸出。return results;
建立名為
RetrieveActiveProductsAsync
的新非同步方法,以傳回IEnumerable<Product>
。public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync() { }
針對後續步驟,在
RetrieveActiveProductsAsync
方法中新增此程式碼。使用 SQL 查詢建立名為
sql
的新字串,以擷取多個欄位,其中篩選條件 (@tagFilter
) 套用至每個項目的 tags 陣列。string sql = """ SELECT p.id, p.name, p.category, p.sku, p.description, p.price FROM products p JOIN tag IN p.tags WHERE STRINGEQUALS(tag, @tagFilter, true) """;
建立名為
query
的新QueryDefinition
變數,並傳入sql
字串作為唯一的查詢參數。 此外,使用WithParameter
流體方法將red
值套用至@tagFilter
參數。var query = new QueryDefinition( query: sql ) .WithParameter("@tagFilter", "red");
使用
GetItemQueryIterator<>
泛型方法和query
變數來建立迭代器,以從 Azure Cosmos DB 取得資料。 將迭代器儲存在名為feed
的變數中。 將此整個運算式包裝在 using 陳述式中,以便稍後處置迭代器。using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>( queryDefinition: query );
使用 while 迴圈逐一查看多頁的結果,並將值儲存在名為 results的泛型
List<>
中。 傳回 results 作為RetrieveActiveProductsAsync
方法的輸出。List<Product> results = new(); while (feed.HasMoreResults) { FeedResponse<Product> response = await feed.ReadNextAsync(); foreach (Product item in response) { results.Add(item); } } return results;
儲存Services/CosmosClient.cs 檔案。
提示
如果您不確定您的程式碼是否正確,您可根據 GitHub 上的範例程式碼檢查原始程式碼。
驗證最終應用程式
最後,您將執行已啟用熱重新載入的應用程式。 執行應用程式會驗證您的程式碼是否可從 API for NoSQL 存取資料。
回到終端機,執行應用程式。
dotnet run
執行命令的輸出應該包含應用程式執行所在的連接埠和 URL 清單。 開啟新的瀏覽器,然後瀏覽至執行中的 Web 應用程式。 觀察執行中應用程式的全部三個頁面。 每個頁面現在都應該包含來自 Azure Cosmos DB 的即時資料。
清除資源
如果不再需要本教學課程中使用的資料庫,請予以刪除。 若要這麼做,請瀏覽至帳戶頁面,選取 [資料總管]、選取 cosmicworks
資料庫,然後選取 [刪除]。
下一步
既然您已使用 Azure Cosmos DB 建立第一個 .NET Web 應用程式,您現在可以深入了解 SDK 以匯入更多資料、執行複雜的查詢,以及管理 Azure Cosmos DB for NoSQL 資源。