Overview
在本指南中,您可以学习;了解如何创建 ASP .NET Core应用程序,该应用程序提供 OData 端点并使用实体框架 (EF) Core 提供程序访问权限MongoDB。 ASP .NET Core 是一个跨平台框架,用于创建基于云的应用程序。 OData 是用于构建和使用 RESTful API 的标准化协议,它允许您使用HTTP请求与数据进行交互。
本教程中的应用程序由以下各层组成:
数据库层:MongoDB提供数据存储和检索。
应用程序层:ASP .NET Core 处理HTTP请求、路由和依赖项注入。
数据访问权限层:EF Core 提供程序提供MongoDB文档映射和 OData查询转换。
为何将MongoDB与 ASP .NET Core 和 OData 结合使用?
本教程使用 ASP .NET Core OData框架和适用于MongoDB 的实体框架 (EF) 核心提供程序来创建可查询的 REST API。 OData 提供了一种统一的数据公开和交互方式,并提供筛选、排序、分页和字段选择等高级查询功能。
通过将MongoDB与 ASP .NET Core 和 OData 集成,您可以使用 EF 熟悉的模式以及 MongoDB 灵活的文档模型和 OData查询功能。这种组合支持需要复杂查询接口、类型安全和基于标准的API设计的应用程序。您可以使用MongoDB、ASP .NET Core 和 OData 创建实际应用程序,例如数据分析仪表盘、报告系统或任何需要复杂数据查询的应用程序。
快速入门教程
本教程向您展示如何构建使用MongoDB、ASP .NET Core 和 EF Core 提供程序的 OData REST API 。该应用程序访问示例餐厅数据,公开符合 OData 的端点,并支持筛选、排序、分页和字段选择等高级查询功能。本教程还包括连接到MongoDB Atlas上托管的MongoDB 集群的说明。
设置您的项目
按照本节中的步骤安装项目依赖项,创建Atlas集群,并设立应用程序结构。
配置数据库连接。
导航到 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集合中餐厅数据的结构,并包括实体框架和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,用于配置模型与根本的数据库之间的关系。该代码将 EF 配置为与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请求中使用 OData查询参数,例如$filter和$orderby。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连接、实体框架 DbContext 和 OData 服务。 OData 配置代码启用以下查询参数,您可以在HTTP端点中使用这些参数:
$select:返回结果中的指定字段$filter:根据过滤条件返回数据$orderby:按指定字段对结果进行排序$expand:在结果中包含相关数据$count:包括结果计数$top:设置最大结果数,限制为100
运行应用程序
最后,按照本部分中的步骤运行OData REST API并使用HTTP请求测试端点。
测试您的 OData 端点。
在另一个终端中,运行以下 curl 命令来测试 OData 端点。每个端点都返回 OData 格式的JSON数据,其中包括 sample_restaurants.restaurants集合中的餐厅信息。如果成功,您的 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"} ]}% 对结果进行排序和计数。
以下命令按
name值对与cuisine筛选器匹配的文档进行过滤,并计算匹配文档的总数: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"} ]}
恭喜完成 EF、ASP .NET和 OData 快速入门教程!完成这些步骤后,您就拥有了一个 ASP .NET Core OData REST API ,它可以连接到MongoDB 部署,使用 OData 端点返回餐厅数据,并支持筛选、排序、分页、字段选择和搜索等高级查询功能。
其他资源
要学习;了解有关本教程中提到的概念的更多信息,请参阅以下资源: