Использование Dapper в ASP.NET WEB API 2 приложении
 
                        
                    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

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

3. Создаем WebApi проект в visual studio
Теперь когда у нас есть каркас, мы можем приступить к созданию базы данных.
4. Создание базы
- Переходим в SQL Management Studio
- Нажимаем правой кнопкой на базы данных и выбираем создать новую

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

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 готов к использованию, давайте протестируем его через постмен и посмотрим что получилось.
Добавление книги

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

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

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

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

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