Overview
このガイドでは、OData エンドポイントを提供し、Entity Framework(FS)コア プロバイダーを使用してMongoDBにアクセスする ASP .NET Coreアプリケーションを作成する方法を学習できます。 ASP .NET Core は、クラウドベースのアプリケーションを作成するためのクロスプラットフォームフレームワークです。 OData は、RESTul API をビルドして消費するための標準化されたプロトコルであり、 HTTPリクエストを使用してデータをやり取りできます。
このチュートリアルのアプリケーションは、次のレイヤーで構成されています。
データベースレイヤー: MongoDB は、データのストレージと検索を提供します。
アプリケーションレイヤー: ASP .NET Core は、 HTTPリクエスト、ルーティング、依存関係インジェクションを処理します。
データ アクセスレイヤー: FS コア プロバイダーは、 MongoDBドキュメントマッピングと OData クエリの変換を提供します。
ASP .NET Core と OData でMongoDBを使用する理由
このチュートリアルでは、ASP .NET Core ODataフレームワークとMongoDB用の Entity Framework(FS)コア プロバイダーを使用して、クエリ可能な REST API を作成します。 OData は、データを公開してやり取りする統一された方法を提供し、フィルタリング、ソート、ページング、フィールド選択などの高度なクエリ機能を提供します。
MongoDB :この組み合わせは、複雑なクエリ インターフェース、型の安全性、標準ベースのAPI設計を必要とするアプリケーションをサポートします。 MongoDB、 ASP .NET Core、OData を使用して、データ分析ダッシュボード、レポート作成システム、複雑なデータクエリを必要とするアプリケーションなどの本番環境のアプリケーションを作成できます。
クイック スタート チュートリアル
このチュートリアルでは、 MongoDB、ASP .NET Core、およびLF Core プロバイダーを使用する OData REST APIを構築する方法について説明します。このアプリケーションは、サンプルレストラン データにアクセスし、OData 準拠のエンドポイントを公開し、フィルタリング、ソート、ページング、フィールド選択などの高度なクエリ機能をサポートします。チュートリアルには、 MongoDB AtlasでホストされているMongoDBクラスターに接続するための手順も含まれています。
Tip
ASP .NET Core を使用せずに FS Core プロバイダーを使用してMongoDBに接続する場合は、 Entity Framework プロバイダーのクイック スタート チュートリアルを参照してください。
プロジェクトを設定する
このセクションの手順に従って、プロジェクトの依存関係のインストール、Atlas クラスターの作成、およびアプリケーション構造の設定を行います。
MongoDB Atlasクラスターを作成します。
MongoDB Atlas は、 MongoDB配置をホストするフルマネージドクラウドデータベースサービスです。 MongoDBデプロイがない場合は、 MongoDBを使い始める チュートリアルを完了することで、 MongoDBクラスターを無料で作成できます。 MongoDBを使い始めるsample_restaurants チュートリアルでは、このチュートリアルで使用される データベースなどのサンプルデータセットをクラスターにロードする方法も説明します。
MongoDBクラスターに接続するには、接続文字列を使用する必要があります。接続文字列を取得する方法については、 MongoDBを使い始めるチュートリアルの「 接続文字列列の追加 」セクションを参照してください。
重要
接続stringを安全な場所に保存します。
データベース接続を構成します。
RestaurantODataApiプロジェクト内の appsettings.jsonファイルに移動し、次のコードを貼り付けます。
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "MongoDB": { "ConnectionString": "<connection string>", "DatabaseName": "sample_restaurants" } }
<connection string> プレースホルダーを、 MongoDBを使い始める チュートリアルから保存した接続文字列に置き換えます。
アプリケーションを作成する
プロジェクト構造と依存関係を設定したら、このセクションの手順に従って、データモデル、DbContext、OData エンドポイントを作成します。
データモデルを作成します。
RestaurantODataApiディレクトリに、Models サブディレクトリを作成します。次に、Modelsディレクトリに Restaurant.cs という名前のファイルを作成し、次のコードを追加します。
using Microsoft.EntityFrameworkCore; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.ComponentModel.DataAnnotations; namespace RestaurantODataApi.Models { public class Restaurant { [] [] [] public string Id { get; set; } = string.Empty; [] public string? Name { get; set; } [] public string? Cuisine { get; set; } [] public string? Borough { get; set; } } }
このモデルクラスは、 MongoDB sample_restaurants.restaurantsコレクションのレストラン データの構造を定義し、 Entity Framework とMongoDB直列化属性を含みます。
データベース接続を構成します。
RestaurantODataApiディレクトリに、RestaurantDbContext.cs という名前のファイルを作成し、次のコードを追加します。
using Microsoft.EntityFrameworkCore; using MongoDB.Driver; using MongoDB.EntityFrameworkCore.Extensions; using RestaurantODataApi.Models; namespace RestaurantODataApi { public class RestaurantDbContext : DbContext { public DbSet<Restaurant> Restaurants { get; set; } public RestaurantDbContext(DbContextOptions<RestaurantDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Configures the Restaurant entity to map to the "restaurants" collection modelBuilder.Entity<Restaurant>().ToCollection("restaurants"); } } }
このクラスは、モデルと基礎となるデータベースの間の関係を構成する DBContext から派生します。このコードは、F をMongoDBで動作するように構成し、Restaurant エンティティをsample_restaurants.restaurants コレクションにマッピングします。
OData コントローラーを作成します。
RestaurantODataApiディレクトリに、Controllers サブディレクトリを作成します。次に、RestaurantsController.cs という名前のファイルを サブディレクトリに追加し、次のコードを貼り付けます。
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.OData.Query; using Microsoft.AspNetCore.OData.Routing.Controllers; using Microsoft.AspNetCore.OData.Routing.Attributes; using RestaurantODataApi.Models; namespace RestaurantODataApi.Controllers { public class RestaurantsController : ODataController { private readonly RestaurantDbContext _context; public RestaurantsController(RestaurantDbContext context) { _context = context; } [] public IQueryable<Restaurant> Get() { return _context.Restaurants; } [] [] public IQueryable<Restaurant> GetRestaurantsByBorough(string borough) { return _context.Restaurants.Where(r => r.Borough == borough); } [] [] public IQueryable<Restaurant> GetRestaurantsByCuisine(string cuisine) { return _context.Restaurants.Where(r => r.Cuisine == cuisine); } } }
このコントローラーは、次の OData REST エンドポイントを定義します。
GET /odata/Restaurants:restaurantsコレクション内のすべてのドキュメントを検索します。EnableQuery属性とその構成オプションを使用すると、 HTTPリクエストで$filterや$orderbyなどの OData クエリ パラメータを使用できます。GET /odata/GetRestaurantsByBorough(borough='{borough}'): 指定されたborough値を持つドキュメントを取得します。GET /odata/GetRestaurantsByCuisine(cuisine='{cuisine}'): 指定されたcuisine値を持つドキュメントを取得します。
アプリケーションロジックを定義します。
Program.csファイルに移動し、その内容を次のコードで置き換えます。
using Microsoft.AspNetCore.OData; using Microsoft.EntityFrameworkCore; using Microsoft.OData.ModelBuilder; using MongoDB.Driver; using RestaurantODataApi; using RestaurantODataApi.Models; var builder = WebApplication.CreateBuilder(args); // Configures the MongoDB connection var connectionString = builder.Configuration["MongoDB:ConnectionString"]; var databaseName = builder.Configuration["MongoDB:DatabaseName"] ?? "sample_restaurants"; if (string.IsNullOrEmpty(connectionString)) { throw new InvalidOperationException("MongoDB connection string is required. Please set MongoDB:ConnectionString in appsettings.json"); } // Registers a MongoDB client builder.Services.AddSingleton<IMongoClient>(sp => new MongoClient(connectionString)); // Registers the DbContext builder.Services.AddDbContext<RestaurantDbContext>(options => { var mongoClient = new MongoClient(connectionString); options.UseMongoDB(mongoClient, databaseName); }); // Configures the OData EDM model var modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet<Restaurant>("Restaurants"); modelBuilder.EntityType<Restaurant>().HasKey(r => r.Id); // Registers the unbound functions var getRestaurantsByBoroughFunction = modelBuilder.Function("GetRestaurantsByBorough"); getRestaurantsByBoroughFunction.Parameter<string>("borough"); getRestaurantsByBoroughFunction.ReturnsCollectionFromEntitySet<Restaurant>("Restaurants"); var getRestaurantsByCuisineFunction = modelBuilder.Function("GetRestaurantsByCuisine"); getRestaurantsByCuisineFunction.Parameter<string>("cuisine"); getRestaurantsByCuisineFunction.ReturnsCollectionFromEntitySet<Restaurant>("Restaurants"); // Configures OData with ASP.NET Core builder.Services.AddControllers() .AddOData(opt => opt .AddRouteComponents("odata", modelBuilder.GetEdmModel()) .Select() .Filter() .OrderBy() .Expand() .Count() .SetMaxTop(100)); var app = builder.Build(); app.UseRouting(); app.MapControllers(); app.Run();
このコードは、 MongoDB接続、Entity Framework DbContext、OData サービスを設定します。 OData 構成コードにより、次のクエリ パラメータが有効になり、 HTTPエンドポイントで使用できます。
$select: 結果内の指定されたフィールドを返します$filter: フィルター条件に基づいてデータを返します$orderby: 指定されたフィールドで結果をソートします$expand: 結果に関連データを含める$count: 結果のカウントを含めます$top: 結果の最大数を設定します。100
アプリケーションの実行
最後に、このセクションの手順に従ってOData REST APIを実行し、 HTTPリクエストを使用してエンドポイントをテストします。
OData エンドポイントをテストします。
別のターミナルで、次の curl コマンドを実行して、OData エンドポイントをテストします。各エンドポイントは、sample_restaurants.restaurantsコレクションのレストラン情報を含む OData形式のJSONデータを返します。成功した場合、curl コマンドはサンプル出力のようなデータを返します。コマンドは結果を 5 ドキュメントに制限します。
すべてのレストランを検索します。
curl 'http://localhost:5236/odata/Restaurants?$top=5' {"@odata.context":"http://localhost:5236/odata/$metadata#Restaurants", "value":[ {"Id":"...","Name":"Riviera Caterer","Cuisine": "American","Borough":"Brooklyn","RestaurantId":"40356018"}, {"Id":"...","Name":"Wilken'S Fine Food","Cuisine": "Delicatessen","Borough":"Brooklyn","RestaurantId":"40356483"}, {"Id":"...","Name":"Kosher Island","Cuisine": "Jewish/Kosher","Borough":"Staten Island","RestaurantId":"40356442"}, {"Id":"...","Name":"Wendy'S","Cuisine":"Hamburgers", "Borough":"Brooklyn","RestaurantId":"30112340"}, {"Id":"...","Name":"Morris Park Bake Shop","Cuisine": "Bakery","Borough":"Bronx","RestaurantId":"30075445"} ]} レストランを地区別にフィルタリングします。
次のコマンドは、
borough値が"Queens"であるレストランを検索します。curl 'http://localhost:5236/odata/GetRestaurantsByBorough(borough=%27Queens%27)?$top=5' {"@odata.context":"http://localhost:5236/odata/$metadata#Restaurants", "value":[ {"Id":"...","Name":"Tov Kosher Kitchen","Cuisine":"Jewish/Kosher", "Borough":"Queens","RestaurantId":"40356068"}, {"Id":"...","Name":"Brunos On The Boulevard","Cuisine":"American", "Borough":"Queens","RestaurantId":"40356151"}, {"Id":"...","Name":"Carvel Ice Cream","Cuisine":"Ice Cream, Gelato, Yogurt, Ices", "Borough":"Queens","RestaurantId":"40361322"}, {"Id":"...","Name":"Sal'S Deli","Cuisine":"Delicatessen", "Borough":"Queens","RestaurantId":"40361618"}, {"Id":"...","Name":"Steve Chu'S Deli & Grocery","Cuisine":"Delicatessen", "Borough":"Queens","RestaurantId":"40361998"} ]} レストランを料理別にフィルタリングします。
次のコマンドは、
cuisine値が"Mexican"であるレストランを検索します。curl 'http://localhost:5236/odata/GetRestaurantsByCuisine(cuisine=%27Mexican%27)?$top=5' {"@odata.context":"http://localhost:5236/odata/$metadata#Restaurants", "value":[ {"Id":"...","Name":"Panchito'S","Cuisine":"Mexican","Borough":"Manhattan"}, {"Id":"...","Name":"Mexico Lindo Restaurant","Cuisine":"Mexican","Borough":"Manhattan"}, {"Id":"...","Name":"Casa Pepe","Cuisine":"Mexican","Borough":"Brooklyn"}, {"Id":"...","Name":"Cuchifrito","Cuisine":"Mexican","Borough":"Manhattan"}, {"Id":"...","Name":"Mary Ann'S","Cuisine":"Mexican","Borough":"Manhattan"} ]}
OData の高度なクエリ機能をテストします。
エンドポイントを使用して、OData クエリ パラメーターと演算子を含めることで、複雑なクエリを実行できます。次の curl コマンドは、これらの機能をテストします。
複数のフィールドでフィルタリングします。
次のコマンドでは、OData クエリ演算子を使用して、
borough値が"Queens"で、かつname値が"Moon"を含むドキュメントを検索します。curl 'http://localhost:5236/odata/Restaurants?$filter=Borough%20eq%20%27Queens%27%20and%20contains(Name,%20%27Moon%27)' {"@odata.context":"http://localhost:5236/odata/$metadata#Restaurants", "value":[ {"Id":"...","Name":"New Moon Star Restaurant","Cuisine":"Chinese","Borough":"Queens"}, {"Id":"...","Name":"Moon Tikka Grill","Cuisine":"Indian","Borough":"Queens"}, {"Id":"...","Name":"Silver Moon Diner","Cuisine":"American","Borough":"Queens"}, {"Id":"...","Name":"Mooney'S Public House","Cuisine":"Irish","Borough":"Queens"}, {"Id":"...","Name":"Moon Light Crill Rest","Cuisine":"Indian","Borough":"Queens"}, {"Id":"...","Name":"Full Moon Cafe","Cuisine":"Café/Coffee/Tea","Borough":"Queens"}, {"Id":"...","Name":"Pacific Moon","Cuisine":"Chinese","Borough":"Queens"}, {"Id":"...","Name":"Moon Palace Kitchen","Cuisine":"Chinese","Borough":"Queens"}, {"Id":"...","Name":"Honey Moon Coffee Shop","Cuisine":"Café/Coffee/Tea","Borough":"Queens"}, {"Id":"...","Name":"Honey Moon Coffee Shop","Cuisine":"Café/Coffee/Tea","Borough":"Queens"} ]}% 結果を順序付けてカウントします。
次のコマンドは、
cuisineフィルターに一致するドキュメントをname値でソートし、一致するドキュメントの合計数をカウントします。curl 'http://localhost:5236/odata/GetRestaurantsByCuisine(cuisine=%27Czech%27)?$orderby=Name&$count=true' {"@odata.context":"http://localhost:5236/odata/$metadata#Restaurants", "@odata.count":6, "value":[ {"Id":"...","Name":"Bohemian Beer Garden","Cuisine":"Czech","Borough":"Queens"}, {"Id":"...","Name":"Brooklyn Beet Company","Cuisine":"Czech","Borough":"Brooklyn"}, {"Id":"...","Name":"Hospoda","Cuisine":"Czech","Borough":"Manhattan"}, {"Id":"...","Name":"Koliba Restaurant","Cuisine":"Czech","Borough":"Queens"}, {"Id":"...","Name":"Milan'S Restaurant","Cuisine":"Czech","Borough":"Brooklyn"}, {"Id":"...","Name":"Olde Prague Tavern","Cuisine":"Czech","Borough":"Queens"} ]}
FS、 ASP .NET 、 OData クイック スタート チュートリアルを完了しました。これらの手順を完了すると、 MongoDBデプロイに接続し、 OData エンドポイントを使用してレストランのデータを返し、 フィルタリング、ソート、ページング、フィールド選択、検索などの高度なREST API機能をサポートする ASP .NET Core OData REST API が作成されます。
追加リソース
このチュートリアルで述べられた概念の詳細については、次のリソースを参照してください。
ASP .NET Core OData ドキュメント
OData Protocol のドキュメント
MongoDB Entity Framework コアプロバイダーのドキュメント