1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        NoSQL | MongoDB入門實戰(zhàn)教程(5)

        共 12096字,需瀏覽 25分鐘

         ·

        2021-07-19 12:14

        【NoSQL| 總結(jié)/Edison Zhou

        前面我們學(xué)習(xí)了MongoDB的基本查詢命令操作,作為后端開發(fā)的我們大部分場景都是在應(yīng)用程序中和MongoDB進行交互,因此本篇我們來學(xué)習(xí)一下如何在ASP.NET Core中集成MongoDB。

        1配置MongoDB

        首先,請參照之前的文章安裝部署好一個MongoDB節(jié)點或集群。

        然后,手動創(chuàng)建一個數(shù)據(jù)庫BookStoreDB 和 一個集合 Books。

        use BookStoreDBdb.CreateCollection('Books')

        最后,預(yù)先插入兩條測試數(shù)據(jù):

        db.Books.insertMany([{'Name':'Design Patterns','Price':54.93,'Category':'Computers','Author':'Ralph Johnson', 'CreatedDate':ISODate("2012-10-02T07:58:51Z"),'UpdatedDate':ISODate("2012-10-02T07:58:51Z")}, {'Name':'Clean Code','Price':43.15,'Category':'Computers','Author':'Robert C. Martin','CreatedDate':ISODate("2012-10-02T07:58:51Z"),'UpdatedDate':ISODate("2012-10-02T07:58:51Z")}])
        2配置ASP.NET Core項目

        創(chuàng)建WebAPI項目

        建立一個ASP.NET Core 或 ASP.NET 5的WebAPI項目。

        通過NuGet安裝MongoDB.Driver:

        PM>Install-Package MongoDB.Driver

        目前MongoDB.Driver最新版本為2.12.4(2021年6月5日發(fā)布)。一般來說,我們操作MongoDB都會選擇這個官方的Driver。

        添加實體模型

        在WebAPI項目中添加Models目錄,并增加 Book 實體類:

        public class Book : MongoDocBase{    [BsonElement("Name")]    public string BookName { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
        public string Author { get; set; }}
        public class MongoDocBase{ [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; }
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)] public DateTime? CreatedDate { get; set; }
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)] public DateTime? UpdatedDate { get; set; }}

        需要注意的是:MongoDB存儲時間類型數(shù)據(jù)時,都是先轉(zhuǎn)換為UTC時間,然后存儲到數(shù)據(jù)庫中。當(dāng)我們?nèi)〕龃鎯Φ臅r間時,就會出現(xiàn)時差的問題。因此,一般我們會給文檔中的日期類型加上如下所示的注解,將它轉(zhuǎn)換為本地時間傳輸:

        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]

        在實際應(yīng)用中,我們會給實體類創(chuàng)建一些DTO,然后在應(yīng)用層進行DTO向DO的轉(zhuǎn)換。因此,這里我們假設(shè)會進行 創(chuàng)建Book 和 修改Book 的操作,創(chuàng)建兩個DTO類:

        (1)CreateBookDto

        public class CreateBookDto{    public string BookName { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
        public string Author { get; set; }
        [JsonIgnore] public DateTime CreatedDate { get; set; } = DateTime.Now;}

        (2)UpdateBookDto

        public class UpdateBookDto : CreateBookDto{    public string Id { get; set; }
        [JsonIgnore] public DateTime UpdatedDate { get; set; } = DateTime.Now;}

        在本示例中,使用AutoMapper進行DTO和DO之間的互轉(zhuǎn),因此,安裝 AutoMapper 及其 擴展:

        PM>Install-Package AutoMapperPM>Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

        創(chuàng)建映射規(guī)則配置:

        public class MappingConfigs : Profile{    public MappingConfigs()    {        CreateMap<CreateBookDto, Book>().ReverseMap();        CreateMap<UpdateBookDto, Book>()            .ForMember(dest => dest.CreatedDate, opt => opt.Ignore())            .ReverseMap();    }}

        添加配置模型

        首先,在appSettings.json中添加以下數(shù)據(jù)庫配置:

        {  ......  "BookstoreDatabaseSettings": {    "BooksCollectionName": "Books",    "ConnectionString": "mongodb://mongo-master:27017",    "DatabaseName": "BookStoreDB"  }}

        需要注意的是:這里的連接字符串指向的是一個沒有設(shè)置用戶名密碼的MongoDB節(jié)點。如果你的MongoDB節(jié)點設(shè)置了用戶名密碼 或者 復(fù)制集分片集 之類的,請修改為匹配的連接字符串。

        然后,創(chuàng)建一個配置項類,也放到Models目錄中:

        namespace EDT.BookStore.API.Models{    public class BookStoreDatabaseSettings : IBookStoreDatabaseSettings    {        public string BooksCollectionName { get; set; }        public string ConnectionString { get; set; }        public string DatabaseName { get; set; }    }
        public interface IBookStoreDatabaseSettings { string BooksCollectionName { get; set; } string ConnectionString { get; set; } string DatabaseName { get; set; } }}

        最后,將其加入到IoC容器中控制:

        public void ConfigureServices(IServiceCollection services){    .....        // AutoMapper Settings    services.AddAutoMapper(typeof(MappingConfigs));
        // MongoDB Settings services.Configure<BookStoreDatabaseSettings>( Configuration.GetSection(nameof(BookStoreDatabaseSettings))); services.AddSingleton<IBookStoreDatabaseSettings>(sp => sp.GetRequiredService<IOptions<BookStoreDatabaseSettings>>().Value);}

        這里,IBookstoreDatabaseSettings 接口使用單一實例服務(wù)生存期在 DI 中注冊。在注入時,接口實例時將解析為 BookStoreDatabaseSettings 對象。

        添加BookService提供CRUD服務(wù)

        在Services目錄下,創(chuàng)建IBookService接口:

        namespace EDT.BookStore.API.Services{    public interface IBookService    {        IList<Book> Get();
        Task<IList<Book>> GetAsync();
        Book Get(string id);
        Task<Book> GetAsync(string id);
        Book Create(Book book);
        Task<Book> CreateAsync(Book book);
        void Update(string id, Book bookIn);
        Task UpdateAsync(string id, Book bookIn);
        void Remove(string id);
        Task RemoveAsync(string id); }}

        然后,創(chuàng)建BookService 實現(xiàn) IBookService 接口。

        namespace EDT.BookStore.API.Services{    public class BookService : IBookService    {        private readonly IMongoCollection<Book> _books;
        public BookService(IBookStoreDatabaseSettings settings) { var mongoClient = new MongoClient(settings.ConnectionString); var mongoDatabase = mongoClient.GetDatabase(settings.DatabaseName); _books = mongoDatabase.GetCollection<Book>(settings.BooksCollectionName); }
        public Book Create(Book book) { _books.InsertOne(book); return book; }
        public async Task<Book> CreateAsync(Book book) { await _books.InsertOneAsync(book); return book; }
        public IList<Book> Get() { return _books.Find(book => true).ToList(); }
        public async Task<IList<Book>> GetAsync() { return await _books.Find(book => true).ToListAsync(); }
        public Book Get(string id) { return _books.Find(book => book.Id == id).FirstOrDefault(); }
        public async Task<Book> GetAsync(string id) { return await _books.Find(book => book.Id == id).FirstOrDefaultAsync(); }
        public void Remove(string id) { _books.DeleteOne(book => book.Id == id); }
        public async Task RemoveAsync(string id) { await _books.DeleteOneAsync(book => book.Id == id); }
        public void Update(string id, Book bookIn) { _books.ReplaceOne(book => book.Id == id, bookIn); }
        public async Task UpdateAsync(string id, Book bookIn) { await _books.ReplaceOneAsync(book => book.Id == id, bookIn); } }}

        在上面的代碼中,會通過構(gòu)造函數(shù)從DI檢索IBookStoreDatabaseSettings實例獲取MongoDB連接字符串、數(shù)據(jù)庫名 和 集合名。

        當(dāng)然,我們也可以使用 約定大于配置 的方式,統(tǒng)一采用實體類的名字 作為默認(rèn)的 集合名,示例如下:

        _books = mongoDatabase.GetCollection<Book>(typeof(Book).Name);

        最后,將BookService也加入到IoC容器中:

        services.AddSingleton<IBookService, BookService>();

        這里,將BookService作為單一實例注入,這是因為 BookService 直接依賴于 MongoClient,而根據(jù)官方Mongo Client重用準(zhǔn)則,我們應(yīng)該使用單一實例服務(wù)在IoC容器中注入MongoClient。

        添加Controller提供應(yīng)用層接口

        在Controllers目錄下,新增 BookController 控制器:

        namespace EDT.BookStore.API.Controllers{    [ApiController]    [Route("[controller]")]    public class BookController : ControllerBase    {        private readonly IMapper _mapper;        private readonly IBookService _bookService;
        public BookController(IMapper mapper, IBookService bookService) { _mapper = mapper; _bookService = bookService; }
        [HttpGet] [ProducesResponseType(typeof(IList<Book>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(IList<Book>), StatusCodes.Status204NoContent)] public async Task<ActionResult<IList<Book>>> Get() { var books = await _bookService.GetAsync(); if (books == null) { return NoContent(); }
        return Ok(books); }
        [HttpGet("{id:length(24)}", Name = "GetBook")] [ProducesResponseType(typeof(Book), StatusCodes.Status200OK)] [ProducesResponseType(typeof(Book), StatusCodes.Status404NotFound)] public async Task<ActionResult<Book>> Get(string id) { var book = await _bookService.GetAsync(id); if (book == null) { return NotFound(); }
        return Ok(book); }
        [HttpPost] [ProducesResponseType(typeof(Book), StatusCodes.Status201Created)] public async Task<ActionResult<Book>> Create(CreateBookDto bookDto) { var book = _mapper.Map<Book>(bookDto); await _bookService.CreateAsync(book); return CreatedAtRoute("GetBook", new { id = book.Id.ToString() }, bookDto); }
        [HttpPut("{id:length(24)}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task<ActionResult> Update(string id, UpdateBookDto bookDto) { var book = await _bookService.GetAsync(id); if (book == null) { return NotFound(); }
        _mapper.Map(bookDto, book);
        await _bookService.UpdateAsync(id, book); return Ok(); }
        [HttpDelete("{id:length(24)}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task<ActionResult> Update(string id) { var book = await _bookService.GetAsync(id); if (book == null) { return NotFound(); }
        await _bookService.RemoveAsync(id); return Ok(); } }}
        3測試ASP.NET Core WebAPI

        生成該ASP.NET Core WebAPI應(yīng)用,啟動之后在Swagger頁面進行測試

        點擊GET /Book接口,測試結(jié)果如下:

        其他接口測試結(jié)果不再贅述,有興趣的童鞋可以自行跑起來測試一下。

        示例github地址:https://github.com/EdisonChou/EDT.Mongo.Sample

        End總結(jié)

        本文總結(jié)了如何在ASP.NET Core/ASP.NET 5應(yīng)用程序中操作MongoDB,展示了一個麻雀雖小但五臟俱全的示例,希望能對你有所幫助。


        參考資料

        Microsoft Doc,使用ASP.NET Core和MongoDB創(chuàng)建WebAPI,傳送門:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-mongo-app?view=aspnetcore-5.0&tabs=visual-studio

        唐建法,《MongoDB高手課》(極客時間)

        郭遠威,《MongoDB實戰(zhàn)指南》(圖書)

        △推薦訂閱學(xué)習(xí)

        歡迎各位讀者加入微信群一起學(xué)習(xí)交流,
        在公眾號后臺回復(fù)“加群”即可~~

        ?

        ?

        瀏覽 55
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            嫩模一区二区 | 欧美裸体xxxx极品少妇 | 欧美老妇人色惰网 | 懂色AV一区二区三区国产中文在线 | 麻豆操屄| 国产精品动漫网站 | 中文字幕啪啪 | 夜夜撸日日干 | 内射一级| 亚洲热视频 |