1.21 jigowatts

Great Scott!

ASP.NET MVCはじめました~MongoDBのデータを削除する

概要

一覧登録更新、CURD処理最後はMongoDBのデータ削除です。

削除画面はこんな感じになります(デフォルト)。
f:id:sh_yoshida:20160916125703p:plain

環境

データの削除

ObjectIdをキーに削除してます。ただしstring型のため、Parseメソッドで変換する必要があります。
■UserRepository.cs

public async Task DeleteAsync(string id)
{
    var collection = GetCollection<User>(Collection);
    var objId = ObjectId.Parse(id);
    var filter = Builders<User>.Filter.Eq("_id", objId);
    await collection.DeleteOneAsync(filter);
}

ラムダ式だとわざわざ変換しなくてもいい感じにやってくれるみたいです。これもBsonRepresentation属性のおかげ。
■UserRepository.cs

public async Task DeleteAsync(string id)
{
    var collection = GetCollection<User>(Collection);
    await collection.DeleteOneAsync(d => d.Id == id);
}

MVC

コードを一式載せておきます。

Model

■User.cs

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

namespace aspnet_mvc5_mongodb.Models
{
    public class User
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

        [BsonElement("name")]
        [Required]
        public string Name { get; set; }

        [BsonElement("age")]
        public int Age { get; set; }

        [BsonElement("email")]
        [Required]
        public string Email { get; set; }

        [BsonElement("address")]
        public string Address { get; set; }

        [BsonElement("revision")]
        public int Revision { get; set; }

        [BsonElement("last_modified")]
        public DateTime LastModified { get; set; }

    }
}

View

■Delete.cshtml

@model aspnet_mvc5_mongodb.Models.User

@{
    ViewBag.Title = "Delete";
}

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>User</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Name)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Age)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Age)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Email)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Email)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Address)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Address)
        </dd>

    </dl>

    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()

        <div class="form-actions no-color">
            <input type="submit" value="Delete" class="btn btn-default" /> |
            @Html.ActionLink("Back to List", "Index")
        </div>
    }
</div>

Controller

■UsersController.cs

using aspnet_mvc5_mongodb.Models;
using aspnet_mvc5_mongodb.Repositories;
using aspnet_mvc5_mongodb.Repositories.Abstractions;
using System;
using System.Net;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace aspnet_mvc5_mongodb.Controllers
{
    public class UsersController : Controller
    {
        private readonly IUserRepository _repository;
        public UsersController()
            : this(new UserRepository())
        {

        }
        public UsersController(IUserRepository repository)
        {
            this._repository = repository;
        }

        [HttpGet]
        public async Task<ActionResult> Delete(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var model = await _repository.GetByIdAsync(id);
            if (model == null)
            {
                return HttpNotFound();
            }

            return View(model);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> DeleteConfirmed(string id)
        {
            await _repository.DeleteAsync(id);
            return RedirectToAction("Index");
        }

        ...
    }
}

リポジトリ

■MongoDB.cs

using MongoDB.Driver;
using System.Configuration;

namespace aspnet_mvc5_mongodb.Repositories
{
    public class MongoDB
    {
        protected static IMongoClient _client;
        protected static IMongoDatabase _database;

        public MongoDB()
        {
            var connectionString = ConfigurationManager.AppSettings["MongoDBConnection"];
            var database = ConfigurationManager.AppSettings["Database"];
            _client = new MongoClient(connectionString);
            _database = _client.GetDatabase(database);
        }

        public static IMongoCollection<T> GetCollection<T>(string collection)
        {
            return _database.GetCollection<T>(collection);
        }

    }
}

■IUserRepository.cs

using aspnet_mvc5_mongodb.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace aspnet_mvc5_mongodb.Repositories.Abstractions
{
    public interface IUserRepository
    {
        Task<User> GetByIdAsync(string id);
        Task DeleteAsync(string id);
        ...
    }
}

■UserRepository.cs

using aspnet_mvc5_mongodb.Models;
using aspnet_mvc5_mongodb.Repositories.Abstractions;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace aspnet_mvc5_mongodb.Repositories
{
    public class UserRepository : MongoDB, IUserRepository
    {
        private static readonly string Collection = "users";

        public async Task<User> GetByIdAsync(string id)
        {
            var collection = GetCollection<User>(Collection);
            return await collection.Find(d => d.Id == id).FirstOrDefaultAsync();
        }

        public async Task DeleteAsync(string id)
        {
            var collection = GetCollection<User>(Collection);
            await collection.DeleteOneAsync(d => d.Id == id);
        }

        ...
    }
}

実行

/Users/Delete/[ObjectId]にアクセス。
f:id:sh_yoshida:20160916125703p:plain

というわけで、ASP.NET MVCでのMongoDBのCRUD処理の表面を撫でてみました☆彡