CRUD บน mongodb ด้วย .NET Core 2.0

วิธีทำให้ .NET Core 2.0 ไปเรียกใช้งาน mongodb ทำได้ผ่าน package ที่ชื่อ MongoDB.Driver (NuGet) วิธีลงก็ตรงไปตรงมาผ่านคำสั่ง dotnet add package

dotnet add package MongoDB.Driver

สมมติว่ามี collection ชื่อ customers อยู่ใน database ชื่อ data ในนั้นมี document ที่มี key เป็น _id ที่มี type เป็น Object ID, name เป็น string และ dob (วันเดือนปีเกิด) เป็น date ใน collection มีอยู่ 5 documents หน้าตาตามรูป


เอาทุก document

วิธีเอาทุก document ใน mongodb มีทั้งเป็นแบบ typed และ untyped ถ้าเป็น typed คือ ดึงออกมาแล้ว cast ใส่ model ที่เราประกาศไว้แล้ว แต่ถ้า untype คือ ดึงออกมาแล้วกลายเป็น BSON document

จดไว้เฉพาะดึงแบบ typed ส่วนแบบ untyped ยังไม่อยากจด

ก่อนจะดึงแบบ typed ก็ประกาศ model มาเอาไว้ใช้เป็น type ก่อน

using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

public class Customer
{
  [BsonRepresentation(BsonType.ObjectId)]
  public string Id { get; set; }
  public string name { get; set; }
  public DateTime dob { get; set; }
}

ตรงฟิลด์ Id มีการใส่ mark ไว้ด้านบนว่า [BsonRepresentation(BsonType.ObjectId)] ด้วย เพื่อให้ตอนเอาไปแสดงผล มันแปลงเป็น string ที่หน้าตาเดียวกันกับ ObjectId ใน mongodb

ตอนดึงข้อมูล ก็จะดึงผ่าน asynchronous ก็จะได้ service ออกมาหน้าตาประมาณนี้

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;

public class CustomerService
{
  private MongoClient client;
  private IMongoDatabase db;
  private IMongoCollection<Customer> col;

  public CustomerService()
  {
    this.client = new MongoClient("mongodb://localhost:27017");
    this.db = client.GetDatabase("data");
    this.col = this.db.GetCollection<Customer>("customers");
  }

  public async Task<IEnumerable<Customer>> All()
  {
    var list = await this.col.Find(new BsonDocument()).ToListAsync();
    return list;
  }
}

สังเกตว่า ตอน .Find จริง ๆ มันรับ filter ตรงนี้ถ้าอยากใส่ filter อะไรก็ใส่ไป แต่ถ้าไม่มี filter ก็ให้ส่ง BsonDocument ไปตัวนึง

พอเอาไปใส่ใน Web API ก็จะออกมาประมาณนี้

[HttpGet]
public async Task<IEnumerable<Customer>> Get () {
    CustomerService cs = new CustomerService ();
    return await cs.All ();
}

เอาแค่ document เดียว

ทำเหมือนตอนเอาทุก document หลัก ๆ คือใส่ filter ให้มันแล้วเอาแค่ตัวแรกเท่านั้นเอง

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;

public class CustomerService
{
  private MongoClient client;
  private IMongoDatabase db;
  private IMongoCollection<Customer> col;

  public CustomerService()
  {
    this.client = new MongoClient("mongodb://localhost:27017");
    this.db = client.GetDatabase("data");
    this.col = this.db.GetCollection<Customer>("customers");
  }

  public async Task<IEnumerable<Customer>> All()
  {
    var list = await this.col.Find(new BsonDocument()).ToListAsync();
    return list;
  }

  public async Task<Customer> Get(string id)
  {
    var cust = await this.col.Find(x => x.Id == id).FirstAsync();
    return cust;
  }
}

พอเอาไปใส่ใน Web API ก็จะได้แบบนี้

[HttpGet ("{id}")]
public async Task<Customer> Get (string id) {
    CustomerService cs = new CustomerService ();
    return await cs.Get (id);
}

สร้างใหม่

ตอนเพิ่มของใหม่ก็ตรงไปตรงมา

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;

public class CustomerService
{
  private MongoClient client;
  private IMongoDatabase db;
  private IMongoCollection<Customer> col;

  public CustomerService()
  {
    this.client = new MongoClient("mongodb://localhost:27017");
    this.db = client.GetDatabase("data");
    this.col = this.db.GetCollection<Customer>("customers");
  }

  public async Task<IEnumerable<Customer>> All()
  {
    var list = await this.col.Find(new BsonDocument()).ToListAsync();
    return list;
  }

  public async Task<Customer> Get(string id)
  {
    var cust = await this.col.Find(x => x.Id == id).FirstAsync();
    return cust;
  }

  public async Task Add(Customer cust)
  {
    await this.col.InsertOneAsync(cust);
  }
}

พอเอาไปใส่ Web API ก็แบบนี้

[HttpPost]
public async Task Post ([FromBody] Customer value) {
    await this.cs.Add (value);
}

อย่าลืมว่าตอนสร้างของใหม่ใส่เข้าไป ไม่ต้องใส่ id ให้มัน Object Id มันเป็น autogenerated value

แก้ไข document เดิม

ตอนแก้ไข document เก่า ใช้วิธี replace ของเก่าด้วย ReplaceOneAsync หรือถ้าอยากจะใช้เป็น UpdateOneAsync ก็แล้วแต่เลย

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;

public class CustomerService
{
  private MongoClient client;
  private IMongoDatabase db;
  private IMongoCollection<Customer> col;

  public CustomerService()
  {
    this.client = new MongoClient("mongodb://localhost:27017");
    this.db = client.GetDatabase("data");
    this.col = this.db.GetCollection<Customer>("customers");
  }

  public async Task<IEnumerable<Customer>> All()
  {
    var list = await this.col.Find(new BsonDocument()).ToListAsync();
    return list;
  }

  public async Task<Customer> Get(string id)
  {
    var cust = await this.col.Find(x => x.Id == id).FirstAsync();
    return cust;
  }

  public async Task Add(Customer cust)
  {
    await this.col.InsertOneAsync(cust);
  }

  public async Task Update(string id, Customer cust)
  {
    await this.col.ReplaceOneAsync(x => x.Id == id, cust);
  }
}

ลบ document

ปิดท้ายด้วย remove นี่ก็ตรงไปตรงมา

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;

public class CustomerService
{
  private MongoClient client;
  private IMongoDatabase db;
  private IMongoCollection<Customer> col;

  public CustomerService()
  {
    this.client = new MongoClient("mongodb://localhost:27017");
    this.db = client.GetDatabase("data");
    this.col = this.db.GetCollection<Customer>("customers");
  }

  public async Task<IEnumerable<Customer>> All()
  {
    var list = await this.col.Find(new BsonDocument()).ToListAsync();
    return list;
  }

  public async Task<Customer> Get(string id)
  {
    var cust = await this.col.Find(x => x.Id == id).FirstAsync();
    return cust;
  }

  public async Task Add(Customer cust)
  {
    await this.col.InsertOneAsync(cust);
  }

  public async Task Update(string id, Customer cust)
  {
    await this.col.ReplaceOneAsync(x => x.Id == id, cust);
  }

  public async Task Remove(string id)
  {
    await this.col.DeleteOneAsync(x => x.Id == id);
  }
}

เอาไปใส่ใน Web API

[HttpDelete ("{id}")]
public async Task Delete (string id) {
    await this.cs.Remove(id);
}

ข้อสังเกต

request ที่ส่งไปหา mongodb เป็น asynchronous ทั้งหมด เลยใช้ async/await มาจัดการ asynchronous requests ทั้งหมด

โค้ดตัวอย่าง

เอาไว้ที่ https://github.com/chonla/MongoDBDotNetCore

ตัวอย่างเพิ่มเติม

Leave a Reply