0 3.7K ru

Использование Dapper в ASP.NET WEB API 2 приложении

Categories: 💻 Programming

Dapper.NET — это «mini-ORM» на которой работает движок StackExchange и сайт StackOverflow  в частности.  Dapper это технология маппинга результатов sql-запросов с классами c#. Dapper чем то похож на Entity Framework, но за счет легковесности Dapper обеспечивает большую производительность и работает быстрее, нежели Entity Framework.

Далее рассмотрим как можно построить  REST'ful api controller с запросами к базе через dapper.

1. Создаем class library для Dapper'a

class library visual studio

2. Подключаем Dapper с nuget'a

dapper .net nuget

3. Создаем WebApi проект в visual studio

Теперь когда у нас есть каркас, мы можем приступить к созданию базы данных. 

4. Создание базы

  • Переходим в SQL Management Studio
  • Нажимаем правой кнопкой на базы данных и выбираем создать новую

создание базы данных в sql management studio

  • Вводим название новой базы (например Dapper) и нажимаем ОК.

dapper database

5. Создаем таблицу "Книги"

для этого выполним следующий sql скрипт:

CREATE TABLE Books (
    Id int NOT NULL IDENTITY,
    Author nvarchar(100) NOT NULL,
    Name nvarchar(250) NOT NULL,
    PageCount int,
    PRIMARY KEY (Id)
);

Теперь когда наша база готова, можем приступать к программированию.

5. Создаем класс Book 

namespace Dapper.Entities
{
    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Author { get; set; }
        public int PageCount { get; set; }
    }
}

6.  Создаем репозиторий для Book

Для класса книга, теперь можно создать репозиторий который будет выполнять CRUD операции.

Создаем интерфейс IBookRepository

using System.Collections.Generic;
using Dapper.Entities;

namespace Dapper.Repositories
{
    public interface IBookRepository
    {
        void Create(Book book);
        void Delete(int id);
        Book Get(int id);
        IEnumerable<Book> GetAllBooks();
        void Update(Book book);
    }
}

И его реализацию BookRepository

using System.Collections.Generic;
using System.Data;
using Dapper.Entities;
using System.Data.SqlClient;
using System.Linq;
using System.Configuration;

namespace Dapper.Repositories
{
    public class BookRepository : IBookRepository
    {
        private readonly string _connectionString = ConfigurationManager.ConnectionStrings["DapperConnection"].ConnectionString;
        public IEnumerable<Book> GetAllBooks()
        {
            using (IDbConnection db = new SqlConnection(_connectionString))
            {
                return db.Query<Book>("SELECT * FROM Books");
            }
        }

        public Book Get(int id)
        {
            using (IDbConnection db = new SqlConnection(_connectionString))
            {
                return db.Query<Book>("SELECT * FROM Books WHERE Id = @id", new { id }).FirstOrDefault();
            }
        }

        public void Create(Book book)
        {
            using (IDbConnection db = new SqlConnection(_connectionString))
            {
                var sqlQuery = "INSERT INTO Books (Name, Author, PageCount) VALUES(@Name, @Author, @PageCount); SELECT CAST(SCOPE_IDENTITY() as int)";
                int userId = db.Query<int>(sqlQuery, book).First();
                book.Id = userId;
            }
        }

        public void Update(Book book)
        {
            using (IDbConnection db = new SqlConnection(_connectionString))
            {
                var sqlQuery = "UPDATE Books SET Name = @Name, Author = @Author, PageCount = @PageCount WHERE Id = @Id";
                db.Execute(sqlQuery, book);
            }
        }

        public void Delete(int id)
        {
            using (IDbConnection db = new SqlConnection(_connectionString))
            {
                var sqlQuery = "DELETE FROM Books WHERE Id = @id";
                db.Execute(sqlQuery, new { id });
            }
        }
    }
}

Следует заметить, что мы используем DapperConnection connectionstring. 

Добавим ее в webapi проект в web.config.

  <add name="DapperConnection" connectionString="Data Source=localhost;Initial Catalog=Dapper;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />

7. Переходим к созданию API BooksController'y

using Dapper.Repositories;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Http;
using Dapper.Entities;

namespace WebApiTest.Controllers
{
    public class BooksController : ApiController
    {
        private readonly IBookRepository _bookRepository = new BookRepository();
        // GET: api/Books
        public async Task<IEnumerable<Book>> Get()
        {
            return _bookRepository.GetAllBooks();
        }

        // GET: api/Books/5
        public Book Get(int id)
        {
            return _bookRepository.Get(id);
        }

        // POST: api/Books
        public IHttpActionResult Post([FromBody]Book book)
        {
            _bookRepository.Create(book);
            return Created(Request.RequestUri + book.Id.ToString(), book);
        }

        // PUT: api/Books/5
        public IHttpActionResult Put(int id, [FromBody]Book book)
        {
            book.Id = id;
            _bookRepository.Update(book);
            return Ok();
        }

        // DELETE: api/Books/5
        public IHttpActionResult Delete(int id)
        {
            _bookRepository.Delete(id);
            return Ok();
        }
    }
}

Следует отметить, что строчка private readonly IBookRepository _bookRepository = new BookRepository(); к использованию не желательна, тут она продемонстрирована ислючительно в качестве примера, я рекомендую использовать какой-то IoC контейнер и инджектить IBookRepository в конструктор.

 

Наш RESTful API готов к использованию, давайте протестируем его через постмен и посмотрим что получилось.

 

Добавление книги

добавление книги

Обновление записи книга

Обновление записи книга postman

Получение списка книг

Получение списка книг

Получение книги по id

Получение книги по id

Удаление книги

Удаление книги

 

Итог:

Dapper это отличный инстумент который подойдет для высоконагруженных и посещаемых enterprise проектов таких как stackexchange. В остальных случаях Entity Framework отлично справляется с задачей основной ORM. Но она требует правильных настроек и правильного подхода к использованию и оптимизации. Если у вас есть достаточно высоконагруженные системы или запросы в них, можно приминять Dapper  для оптимизации этих запросов (или же в EF использовать команду SqlQuery и писать чистый sql)  так как Dapper работает в разы быстрее остальных ORM.

Comments:

Please log in to be able add comments.