Использование 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); IEnumerableGetAllBooks(); 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 IEnumerableGetAllBooks() < using (IDbConnection db = new SqlConnection(_connectionString)) < return db.Query("SELECT * FROM Books"); > > public Book Get(int id) < using (IDbConnection db = new SqlConnection(_connectionString)) < return db.Query("SELECT * FROM Books WHERE 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(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 db.Execute(sqlQuery, book); >> public void Delete(int id) < using (IDbConnection db = new SqlConnection(_connectionString)) < var sqlQuery = "DELETE FROM Books WHERE db.Execute(sqlQuery, new < id >); > > > >
Следует заметить, что мы используем DapperConnection connectionstring.
Добавим ее в webapi проект в web.config.
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> 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 готов к использованию, давайте протестируем его через постмен и посмотрим что получилось.
Dapper что это такое
Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Последнее обновление: 1.11.2015
Dapper представляет собой технологию сопоставления (маппинга) результатов sql-запросов с классами c#. В этом плане Dapper немного похож на Entity Framework. В то же время за счет своей легковесности Dapper обеспечивает большую производительность и быстрее позволяет выполнять запросы, нежели Entity Framework.
Рассмотрим, как мы можем использовать Dapper. Вначале добавим Dapper в наш проект:
Затем определим модель User, с которой мы будем работать:
public class User < public int Id < get; set; >public string Name < get; set; >public int Age < get; set; >>
И добавим в проект в папку App_Data новую базу данных, которую назовем userstore. Далее в этой базе данных определим одну таблицу, которая соответствует описанию модели User:
Затем также добавим в папку Models класс репозитория UserRepository:
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Linq; using Dapper; namespace DapperApplication.Models < public class UserRepository < string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; public ListGetUsers() < Listusers = new List(); using(IDbConnection db = new SqlConnection(connectionString)) < users = db.Query("SELECT * FROM Users").ToList(); > return users; > public User Get(int id) < User user = null; using (IDbConnection db = new SqlConnection(connectionString)) < user = db.Query("SELECT * FROM Users WHERE new < id >).FirstOrDefault(); > return user; > public User Create(User user) < using (IDbConnection db = new SqlConnection(connectionString)) < var sqlQuery = "INSERT INTO Users (Name, Age) VALUES(@Name, @Age); SELECT CAST(SCOPE_IDENTITY() as int)"; int? userId = db.Query(sqlQuery, user).FirstOrDefault(); user.Id = userId; > return user; > public void Update(User user) < using (IDbConnection db = new SqlConnection(connectionString)) < var sqlQuery = "UPDATE Users SET Name = @Name, Age = @Age WHERE db.Execute(sqlQuery, user); >> public void Delete(int id) < using (IDbConnection db = new SqlConnection(connectionString)) < var sqlQuery = "DELETE FROM Users WHERE db.Execute(sqlQuery, new < id >); > > > >
Для осуществления запросов Dapper предоставляет для объектов IDbConnection метод расширения Query , который в качестве параметра принимает sql-выражение и может возвращать объект типа T, с которым сопоставляются результаты запроса.
Затем в файле web.config определим подключение, которое будет использоваться:
И затем определим контроллер, который будет использовать репозиторий для работы с пользователями:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using DapperApplication.Models; namespace DapperApplication.Controllers < public class UsersController : Controller < UserRepository repo = new UserRepository(); public ActionResult Index() < return View(repo.GetUsers()); >public ActionResult Details(int id) < User user = repo.Get(id); if(user!=null) return View(user); return HttpNotFound(); >public ActionResult Create() < return View(); >[HttpPost] public ActionResult Create(User user) < repo.Create(user); return RedirectToAction("Index"); >public ActionResult Edit(int id) < User user = repo.Get(id); if (user != null) return View(user); return HttpNotFound(); >[HttpPost] public ActionResult Edit(User user) < repo.Update(user); return RedirectToAction("Index"); >[HttpGet] [ActionName("Delete")] public ActionResult ConfirmDelete(int id) < User user = repo.Get(id); if (user != null) return View(user); return HttpNotFound(); >[HttpPost] public ActionResult Delete(int id) < repo.Delete(id); return RedirectToAction("Index"); >> >
Dapper
Dapper представляет собой инструмент от компании Stack Exchange, который сопоставляет результаты sql-запросов с классами c#. В этом плане Dapper немного похож на Entity Framework. Однако за счет своей легковесности Dapper обеспечивает большую производительность и быстрее позволяет выполнять запросы, чем EF Core. В частности, dapper применяется в работе сайта stackoverflow.com.
Исходные коды dapper, а также ряд дополнительнйо информации по библиотеке можно найти на официальном репозитории на https://github.com/StackExchange/Dapper.
Для работы с Dapper создадим новый проект ASP.NET Core по типу ASP.NET Core Web App (Model-View-Controller). И вначале добавим в него через Nuget пакеты Microsoft.Data.SqlClient и Dapper (при работе с Dapper используется функционал пакета Microsoft.Data.SqlClient):
Затем определим модель User, с которой мы будем работать:
public class User < public int Id < get; set; >public string Name < get; set; >public int Age < get; set; >>
Для работы с Dapper создадим на MS SQL Server небольшую базу данных, которую назовем userstore. Далее в этой базе данных определим одну таблицу, которая соответствует описанию модели User и имеет три поля Id, Name и Age:
Затем также добавим в папку Models интерфейс и класс репозитория, через который будем работать с базой данных:
using Dapper; using System.Collections.Generic; using System.Data; using Microsoft.Data.SqlClient; using System.Linq; namespace DapperMvcApp.Models < public interface IUserRepository < void Create(User user); void Delete(int id); User Get(int id); ListGetUsers(); void Update(User user); > public class UserRepository : IUserRepository < string connectionString = null; public UserRepository(string conn) < connectionString = conn; >public List GetUsers() < using (IDbConnection db = new SqlConnection(connectionString)) < return db.Query("SELECT * FROM Users").ToList(); > > public User Get(int id) < using (IDbConnection db = new SqlConnection(connectionString)) < return db.Query("SELECT * FROM Users WHERE new < id >).FirstOrDefault(); > > public void Create(User user) < using (IDbConnection db = new SqlConnection(connectionString)) < var sqlQuery = "INSERT INTO Users (Name, Age) VALUES(@Name, @Age)"; db.Execute(sqlQuery, user); // если мы хотим получить id добавленного пользователя //var sqlQuery = "INSERT INTO Users (Name, Age) VALUES(@Name, @Age); SELECT CAST(SCOPE_IDENTITY() as int)"; //int? userId = db.Query(sqlQuery, user).FirstOrDefault(); //user.Id = userId.Value; > > public void Update(User user) < using (IDbConnection db = new SqlConnection(connectionString)) < var sqlQuery = "UPDATE Users SET Name = @Name, Age = @Age WHERE db.Execute(sqlQuery, user); >> public void Delete(int id) < using (IDbConnection db = new SqlConnection(connectionString)) < var sqlQuery = "DELETE FROM Users WHERE db.Execute(sqlQuery, new < id >); > > > >
Для осуществления запросов Dapper предоставляет для объектов IDbConnection метод расширения Query , который в качестве параметра принимает sql-выражение и может возвращать объект типа T, с которым сопоставляются результаты запроса.
Если нужно просто выполнить запрос без необходимости возвращать результат, как в случае с добавлением, обновлением, удалением, то можно использовать метод Execute , в который передается sql-выражение и набор параметров для этого выражения.
Далее изменим файл Startup.cs :
using DapperMvcApp.Models; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; namespace DapperMvcApp < public class Startup < public void ConfigureServices(IServiceCollection services) < string connectionString = "Server=.\\SQLEXPRESS;Initial Catalog=userstore;Integrated Security=True"; services.AddTransient(provider => new UserRepository(connectionString)); services.AddControllersWithViews(); > public void Configure(IApplicationBuilder app) < app.UseDeveloperExceptionPage(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints =>< endpoints.MapControllerRoute( name: "default", pattern: "//"); >); > > >
С помощью механизма внедрения зависимостей здесь устанавливается зависимость для интерфейса IUserRepository в виде объекта UserRepository, в конструктор которого передается строка подключения к бд.
В этом случае контроллер HomeController для взаимодействия с бд и выполнения всех базовых CRUD-операций мог бы выглядеть следующим образом:
using Microsoft.AspNetCore.Mvc; using DapperMvcApp.Models; namespace DapperMvcApp.Controllers < public class HomeController : Controller < IUserRepository repo; public HomeController(IUserRepository r) < repo = r; >public ActionResult Index() < return View(repo.GetUsers()); >public ActionResult Details(int id) < User user = repo.Get(id); if (user != null) return View(user); return NotFound(); >public ActionResult Create() < return View(); >[HttpPost] public ActionResult Create(User user) < repo.Create(user); return RedirectToAction("Index"); >public ActionResult Edit(int id) < User user = repo.Get(id); if (user != null) return View(user); return NotFound(); >[HttpPost] public ActionResult Edit(User user) < repo.Update(user); return RedirectToAction("Index"); >[HttpGet] [ActionName("Delete")] public ActionResult ConfirmDelete(int id) < User user = repo.Get(id); if (user != null) return View(user); return NotFound(); >[HttpPost] public ActionResult Delete(int id) < repo.Delete(id); return RedirectToAction("Index"); >> >
Представления в этом случае могли бы выглядеть следующим образом. Представление Index.cshtml для вывода списка пользователей:
@model IEnumerable @ < ViewData["Title"] = "Список пользователей"; >@ViewData["Title"]
Добавить
Имя | Возраст | |
---|---|---|
@item.Name | @item.Age | Изменить | Удалить |
Представление Create.cshtml для добавления пользователей:
@model DapperMvcApp.Models.User @ < ViewData["Title"] = "Новый пользователь"; >@ViewData["Title"]
Представление Edit.cshtml для редактирования пользователей:
@model DapperMvcApp.Models.User @ < ViewData["Title"] = "Редактировать пользователя"; >@ViewData["Title"].
И представление Delete.cshtml для удаления пользователя:
@model DapperMvcApp.Models.User @ < ViewData["Title"] = "Удаление пользователя"; >@ViewBag.Title
- Имя
- @Model.Name
- Возраст
- @Model.Age
Запустим приложение и добавим пользователя:
Затем мы его сможем увидеть в списке пользователей:
Использование Dapper C# в программировании
Отинчиев, А. К. Использование Dapper C# в программировании / А. К. Отинчиев, Л. Г. Касенова. — Текст : непосредственный // Актуальные вопросы технических наук : материалы V Междунар. науч. конф. (г. Санкт-Петербург, февраль 2019 г.). — Санкт-Петербург : Свое издательство, 2019. — С. 5-8. — URL: https://moluch.ru/conf/tech/archive/324/14815/ (дата обращения: 29.10.2023).
В данной статье рассматривается проблема обработки больших данных в современных системах. Возможность использования инновационной программы для качественной, быстрой и легкодоступной системы.
Ключевые слова: sql, C#, кросс-платформенность, open source, CRUD методы.
This article presents the problems of big data processing in modern systems. The ability to use innovative programs for high-quality, fast and easily accessible system.
Keywords: sql, C#, cross-platform, open source, CRUD methods
Dapper ASP.NET CORE — инструмент созданный компание Stack Exchange, который преобразует результаты sql запросов с классами C#. У Dapper есть схожести с Entity Framework. Благодаря своему малому весу Dapper предоставляет высокую производительность и позволяет выполнять запросы быстрее, чем EF Core, а так же быстрее Entity Framework в 10 раз(Рис 1). Dapper применяется в работе сайта stackoverflow.com, на котором разработчики со всего мира могут задавать ответы по программированию и получать качественные ответы.
Рис. 1. Сравнение скоростей
Платформа ASP.NET Core технология от компании Microsoft, предназначенную для создания веб-приложений: от простых веб-сайтов до огромных веб-порталов и веб-сервисов.
ASP.NET Core представляет собой следующим этапом развития платформы ASP.NET. Но с другой стороны, это не просто очередной релиз. Появление ASP.NET Core в действительности означает революцию всей платформы, ее качественное изменение. Создание платформы началась еще в 2014 году. Первое название платформы условно называлась ASP.NET vNext. В июне 2016 года вышел первый релиз платформы. А в мае 2018 года вышла версия ASP.NET Core 2.1. ASP.NET Core теперь полностью является opensource-фреймворком.
В качестве инструментария разработки мы можем использовать последние выпуски Visual Studio, начиная с версии Visual Studio 2015. Кроме того, мы можем создавать приложения в среде Visual Studio Code, которая является кросс-платформенной и может работать как на Windows, так и на Mac OS X и Linux. Для обработки запросов теперь используется новый конвейер HTTP, который основан на компонентах Katana и спецификации OWIN. А его модульность позволяет легко добавить свои собственные компоненты. Если суммировать, то можно выделить следующие ключевые отличия ASP.NET Core от предыдущих версий ASP.NET:
Переработанный легковесный и модульный конвейер HTTP-запросов
Возможность развертывать приложение как на IIS, так и в рамках своего собственного процесса
Использование пакетов платформы через NuGet
Единый стек веб-разработки, сочетающий Web UI и Web API Конфигурация для упрощенного использования в облаке
Встроенная поддержка для внедрения зависимостей
Кроссплатформенность: возможность разработки и развертывания приложений ASP.NET на Mac, Windows и Linux
Развитие как open source, открытость к изменениям
Для работы нужно подключить в Nuget Dapper (Рис 2)
Рис. 2. Nuget Dapper
Проект можно разделить по папкам для оптимальной работы (Рис 3), Content используется для хранения фотографий и файлов HTML & CSS, Controller центральный компонент в архитектуре проекта, отвечающий за вводом пользователя, обработкой данными и возврату результата, Helpers методы которые часто вызываются, для того чтобы не писать огромный код каждый раз, его можно создать как хелпер и вызывать его, данная механика убирает лишние строки кода, requests это DTO (DTO это Data Transfer Object — шаблон проектирования, использующийся для передачи информации между подсистемами приложения) которые принимают данные с FrontEnd, Domain Models модели принимаемых данных, Repositories классы которые содержат запросы к базе MsSql.
В Dapper можно использовать CRUD методы (Create, Read, Update, Delete).
Существуют специальные запросы, которые могут ускорить процесс сбора данных и комфортного чтения кода.
Рассмотрим на модели User:
public class ProjectsUsers
public string FirstName
public string LastName
public string Grade
1) public IEnumerable List()
var sql = “SELECT * FROM Project.Department_User ”
return Connection.Query (sql);
2) public IEnumerable List()
В данном случае мы можем увидеть, что в первом примере создается переменная sql в которую мы записываем запрос в базу данных, названия таблиц может быть довольно длинными и нечитабельными
Во втором примере наглядно видно, что вызывается метод GetAll(), этот запрос записан в библиотеке Dapper, данная форма вызова оптимальна, читабельна для разработчика и требует меньше строк кода, что может сыграть на скорости выполнения задач.
1) public void Update(ProjectsUsers users)
SET firstName = @firstname,
2) public void Update(ProjectsUsers users)
Connection.Update(users);
При обновлении таблицы Project.Department_User заметно как отличаются запросы к базе данных, в первом примере мы вводим каждую строку из модели ProjectsUsers и таких моделей может быть множество, что может сказаться на быстродействии, во втором примере все просто написано в одну строку.
Dapper на данный момент один из самых удобных инструментов для работы с большими данными, прост в освоении, универсальный для API, высокопроизводительный, скоростной и легковесный ORM.
- Kevin Davis, Notoriously Dapper: How to Be a Modern Gentleman with Manners, Style and Body Confidence Paperback.
- Ben Albahari, C# 6.0 in a Nutshell: The Definitive Reference.
- Maheshwari, Data Analytics Made Accessible.
- Simon, Too Big to Ignore: The Business Case for Big Data
Основные термины (генерируются автоматически): CRUD, API, CORE, FROM, HTTP, IIS, ORM, OWIN, SELECT, SET.
Ключевые слова
SQL, C#, кросс-платформенность, open source, CRUD методы
Похожие статьи
Оптимизация взаимодействия web-приложения с базой данных.
В данной работе проведено исследование производительности ORM-библиотек, на основании которого выбрана библиотека для работы с. Оптимизация взаимодействия web-приложения с базой данных в информационно-исследовательской системе «Шлаковые расплавы».
Слушатель события обновления сцены. Кадронезависимое.
Приводится решение кадронезависимого движения в приложениях под Android на примере классов фреймворка PeeKaBoo. Описывается создание слушателя обновления сцены, зависящего от времени, выбранного разработчиком игры.
Модификация архитектуры web-приложения, основанной на.
В работе рассматривается способ организации архитектуры web-приложения на основе паттерна CQRS. В основе архитектуры лежит разделение на write- и read- модели, которые используют SQL и NoSql базы данных. Результатом применения архитектуры стало возможность.
Исследование производительности ASP.NET-приложений
− Использование HTTP-сжатия. Это самое простое правило, так как для его соблюдения чаще всего не требуется дополнительных затрат
Причем в ASP.NET реализованы так называемые профили кэширования. Они позволяют заранее создать в файле web.config настройки.
Системы сбора информации в аспекте кибербезопасности
Легкость настройки системы. Минимальная нагрузка системы на узлы. Универсальная система, не зависящая от ОС, используемой на узлах.
– Система должна иметь возможность извлекать данные анализа для визуализации через API или иметь средство визуализации данных анализа.
Эволюция веб-фреймворков Microsoft. ASP.NET vNext (ASP.NET 5)
Данная статья рассказывает о платформе Microsoft.NET Framework и технологии создания веб-приложений и веб-сервисов от вышеупомянутой компании — ASP.NET. Описывается история развития данной технологии и последние новшества, такие как ASP.NET vNext.
Интеграция Telegram-ботов в информационных системах
В статье раскрывается понятие о создания Telegram ботов для автоматизации получения информации с информационных систем. Даются определения информационной системы и интеграции с базой данных. Делается вывод, что с помощью ботов можно получить.
Организация сбора технологических данных с буровой и передачи.
Автоматизация технологического процесса составляет важную часть научно-технического прогресса в проведении геологоразведочных работ. Теоретические исследования в области совершенствования управления процессом бурения и его оптимизации получили новые.