五、.Net Core Web Api连接MongoDB自动创建表格并实现CRUD功能
1.注册MongoDB账号,并获取Connection String;
MongoDB官网:MongoDB: The Developer Data Platform | MongoDB
获取Connection String教程:Connection String 获取
-
在VSCode for Mac按下shift+command+p搜索 Nuget Package Manager: Add Package,给项目添加包
-
搜索包:MongoDB.Driver,Microsoft.EntityFrameworkCore,MongoDB.EntityFrameworkCore
-
MongoDB.Driver选择最新版本即可,如最新版本不适配您当前的.Net版本,请尝试根据MongoDB官网有关MongoDB.Driver的兼容性来进行安装:兼容性 - C#/.NET v2.28 (mongodb.com);
Microsoft.EntityFrameworkCore和MongoDB.EntityFrameworkCore包选择8.x版本。
-
在Web Api的appsetting.Development.json 添加MongoDB信息,在ConnectionString的值中填入在MongoDB官网获取的ConnectionString;
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "TeachingAppDatabase": { "BooksCollectionName": "books", "ConnectionString": "Fill it with your MongoDB connection string", "DatabaseName": "teaching_blazor_app" } }
-
创建Config/MongoDbConfiguration.cs,对应appsettings.Development.json中的参数。
using System; namespace TeachingWebApi.Config { public class TeachingAppDatabaseSettings { public string BooksCollectionName { get; init; } public string ConnectionString { get; init; } public string DatabaseName { get; init; } } }
-
在Program.cs中加入以下服务,通过IConfiguration读取appsettings.Development.json中的参数。
builder.Services.Configure<TeachingAppDatabaseSettings>( builder.Configuration.GetSection("TeachingAppDatabase"));
-
创建BookService.cs添加 CRUD 操作服务.
using Microsoft.Extensions.Options; using MongoDB.Driver; using TeachingWebApi.Config; using TeachingWebApi.Models; namespace TeachingWebApi.Services; public class BooksService { private readonly IMongoCollection<Book> _booksCollection; public BooksService( IOptions<TeachingAppDatabaseSettings> mongoDatabaseSettings) { var mongoClient = new MongoClient( mongoDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( mongoDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( mongoDatabaseSettings.Value.BooksCollectionName); } public async Task<List<Book>> GetAsync() => await _booksCollection.Find(_ => true).ToListAsync(); public async Task<Book?> GetAsync(string id) => await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync(); public async Task CreateAsync(Book newBook) => await _booksCollection.InsertOneAsync(newBook); public async Task UpdateAsync(string id, Book updatedBook) => await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook); public async Task RemoveAsync(string id) => await _booksCollection.DeleteOneAsync(x => x.Id == id); }
-
新建一个BookController.cs,实现CRUD;
using Microsoft.AspNetCore.Mvc; using TeachingWebApi.Models; using TeachingWebApi.Services; namespace BookStoreApi.Controllers; [ApiController] [Route("api/[controller]")] public class BooksController : ControllerBase { private readonly BooksService _booksService; public BooksController(BooksService booksService) => _booksService = booksService; [HttpGet] public async Task<List<Book>> Get() => await _booksService.GetAsync(); [HttpGet("{id:length(24)}")] public async Task<ActionResult<Book>> Get(string id) { var book = await _booksService.GetAsync(id); if (book is null) { return NotFound(); } return book; } [HttpPost] public async Task<IActionResult> Post(Book newBook) { await _booksService.CreateAsync(newBook); return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook); } [HttpPut("{id:length(24)}")] public async Task<IActionResult> Update(string id, Book updatedBook) { var book = await _booksService.GetAsync(id); if (book is null) { return NotFound(); } updatedBook.Id = book.Id; await _booksService.UpdateAsync(id, updatedBook); return NoContent(); } [HttpDelete("{id:length(24)}")] public async Task<IActionResult> Delete(string id) { var book = await _booksService.GetAsync(id); if (book is null) { return NotFound(); } await _booksService.RemoveAsync(id); return NoContent(); } }
-
添加代码到Program.cs,以向 DI 注册
BooksService
类,以支持消费类中的构造函数注入。 单一实例服务生存期是最合适的,因为BooksService
直接依赖于MongoClient
。 根据官方 Mongo Client 重用准则,应使用单一实例服务生存期在 DI 中注册MongoClient
。builder.Services.AddSingleton<BooksService>();
-
新建类MongoDBContext.cs,负责连接MongoDB的上下文类;
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using MongoDB.Driver; using TeachingWebApi.Config; using TeachingWebApi.Models; namespace TeachingWebApi.Utils.Data { public class MongoDbContext : DbContext { public readonly IMongoDatabase _db; private readonly string _booksCollectionName; private readonly IOptions<TeachingAppDatabaseSettings> _setting; public MongoDbContext(IOptions<TeachingAppDatabaseSettings> setting) { _setting = setting; var client = new MongoClient(_setting.Value.ConnectionString); _db = client.GetDatabase(_setting.Value.DatabaseName); _booksCollectionName = _setting.Value.BooksCollectionName; } public IMongoCollection<Book> Books => _db.GetCollection<Book>(_booksCollectionName); } }
-
添加类DatabaseSeeder.cs,负责初始化数据库;
using Microsoft.Extensions.Localization; using Microsoft.AspNetCore.Identity; using MongoDB.Driver; using TeachingWebApi.Utils.Data; namespace CoolWebApi.Data.Seeder { public class DatabaseSeeder { private readonly MongoDbContext _dbContext; public DatabaseSeeder( MongoDbContext dbContext) { _dbContext = dbContext; } public void Initialize() { InitializeCollection(); } public async void InitializeCollection() { await CreateCollection("books"); } private async Task CreateCollection(string collectionName) { if (!CollectionExists(_dbContext._db, collectionName)) { await _dbContext._db.CreateCollectionAsync(collectionName, new CreateCollectionOptions { Capped = false }); Console.WriteLine("Collection created!"); } } private bool CollectionExists(IMongoDatabase database, string collectionName) { return database.ListCollectionNames().ToList().Contains(collectionName); } } }
-
在Program.cs添加数据库支持,使用Microsoft.EntityFrameworkCore和MongoDB.EntityFrameworkCore包,当项目运行时会执行DatabaseSeeder.cs和MongoDbContext.cs这两个类,实现初始化项目时生成数据库表;
builder.Services .AddTransient<DatabaseSeeder>() .AddDbContext<MongoDbContext>(options => options .UseMongoDB(new MongoClient(MongoDbConectionString), "teaching_blazor_app"));
-
运行应用,记得将ConnectionString里的改成自己的密码,不然会报认证失败的错误;
-
可以看到MongoDB的Collections已经自动生成了Books表,使用Swagger进行测试;