ASP.NET MVC Web Application CRUD Using RepoDB ORM
Happy Sunday Awesome Programmers!
See the ASP.NET Core MVC version of this tutorial here Create An ASP.NET Core MVC CRUD Website Using RepoDB ORM And SQL Server
Next is to create an ASP.NET MVC project and add via NuGet the RepoDb.SqlServer ORM. This library specifically targets the SQL Server database.
After that, call the bootstrapper to initialize all dependencies for SQL Server in Global.asax.cs Application_Start() method.
Add a BookDetails model class in your project with attributes that would match the db schema.
Add an interface called IBookDetailsRepository that defines the Data Access and CRUD (Create, Read, Update, Delete) functionalities.
Then define a class that implements the methods of interface. This class contains the actual CRUD statements and uses the fluent syntax of the ORM. Make sure to add the using RepoDb; statement to be able to access the underlying methods of the ORM.
Add a service class that calls the repository methods. This will be the intermediary between the controller and repository classes.
As stated above, the controller class instantiates the service class and calls its methods in the controller ActionResult functions.
The views that the user will interact with are the following.
Index.cshtml
Create.cshtml
Edit.cshtml
Delete.cshtml
Output
Happy coding!
See the ASP.NET Core MVC version of this tutorial here Create An ASP.NET Core MVC CRUD Website Using RepoDB ORM And SQL Server
A week ago, I received a newsletter regarding a promising ORM called RepoDB. This ORM library is created by Michael Pendon who is an application architect in Europe. According to him, RepoDB is an open-source . NET ORM library that bridges the gaps of micro-ORMs and full-ORMs. It helps you simplify the switch-over of when to use the BASIC and ADVANCE operations during the development. It is your best alternative ORM to both Dapper and EntityFramework. It also provides query support to several databases such as MySQL, SQL Server, PostGreSQL and there's a survey that this ORM's performance is faster than Dapper. I've used Dapper before and Entity framework in my ASP.NET MVC applications so, it's time to try using this tool by creating a simple ASP.NET MVC CRUD Application(Create, Read, Update, Delete) Application. For the database part, create a ficticious table in your db called BookDetails.
USE [DemoDB] GO /****** Object: Table [dbo].[BookDetails] Script Date: 11/2/2020 12:26:53 PM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[BookDetails]( [BookSerialNo] [int] IDENTITY(1,1) NOT NULL, [BookISBN] [nchar](15) NULL, [BookTitle] [varchar](120) NULL, [BookAuthor] [varchar](60) NULL, [BookPublisher] [varchar](50) NULL, [BookCategory] [varchar](20) NULL, PRIMARY KEY CLUSTERED ( [BookSerialNo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); RepoDb.SqlServerBootstrap.Initialize(); }
public class BookDetails { public int BookSerialNo { get; set; } [Required] [Display(Name = "ISBN")] public string BookISBN { get; set; } [Required] [Display(Name = "Title")] public string BookTitle { get; set; } [Required] [Display(Name = "Author")] public string BookAuthor { get; set; } [Required] [Display(Name = "Publisher")] public string BookPublisher { get; set; } [Required] [Display(Name = "Category")] public string BookCategory { get; set; } }
public interface IBookDetailsRepository { List<BookDetails> GetAll(); BookDetails FindById(int BookSerialNo); bool AddBookDetail(BookDetails book); bool UpdateBookDetail(BookDetails book); bool DeleteBookDetail(int BookSerialNo); }
public class BookDetailsRepository : IBookDetailsRepository { private readonly string connectionString; public BookDetailsRepository() { this.connectionString = ConfigurationManager.ConnectionStrings["BookApplication"].ConnectionString; } public bool AddBookDetail(BookDetails book) { int serialNumber = 0; try { using (var connection = new SqlConnection(this.connectionString)) { var item = new BookDetails() { BookAuthor = book.BookAuthor, BookCategory = book.BookCategory, BookISBN = book.BookISBN, BookTitle = book.BookTitle, BookPublisher = book.BookPublisher }; serialNumber = (int)connection.Insert<BookDetails>(item); } } catch (Exception ex) { return false; } return true; } public bool DeleteBookDetail(int BookSerialNo) { int affectedRows = 0; try { using (var connection = new SqlConnection(this.connectionString)) { affectedRows = (int)connection.Delete<BookDetails>(BookSerialNo); } } catch (Exception ex) { return false; } return true; } public BookDetails FindById(int BookSerialNo) { BookDetails result; result = new BookDetails(); try { using (var connection = new SqlConnection(this.connectionString)) { result = connection.Query<BookDetails>(x => x.BookSerialNo == BookSerialNo).FirstOrDefault(); } } catch (Exception ex) { return null; } return result; } public List<BookDetails> GetAll() { List<BookDetails> lstBooks; lstBooks = new List<BookDetails>(); try { using (var connection = new SqlConnection(this.connectionString)) { connection.Open(); lstBooks = connection.QueryAll<BookDetails>().ToList(); } } catch (Exception ex) { return null; } return lstBooks; } public bool UpdateBookDetail(BookDetails book) { int affectedRows = 0; try { using (var connection = new SqlConnection(this.connectionString)) { var item = new BookDetails() { BookSerialNo = book.BookSerialNo, BookAuthor = book.BookAuthor, BookCategory = book.BookCategory, BookISBN = book.BookISBN, BookTitle = book.BookTitle, BookPublisher = book.BookPublisher }; affectedRows = (int)connection.Update<BookDetails>(item); } } catch (Exception ex) { return false; } return true; } }
public class BookService { private IBookDetailsRepository _repository; public BookService() { _repository = new BookDetailsRepository(); } public List<BookDetails> GetAll() { return _repository.GetAll(); } public BookDetails FindById(int SerialNo) { return _repository.FindById(SerialNo); } public bool AddBookDetails(BookDetails item) { return _repository.AddBookDetail(item); } public bool UpdateBookDetails(BookDetails item) { return _repository.UpdateBookDetail(item); } public bool DeleteBookDetail(int SerialNo) { return _repository.DeleteBookDetail(SerialNo); } }
public class BooksController : Controller { private BookService _service; public BooksController() { _service = new BookService(); } public ActionResult Index() { var model = _service.GetAll(); return View(model); } public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(BookDetails book) { try { _service.AddBookDetails(book); return RedirectToAction("Index"); } catch { return View(); } } public ActionResult Edit(int id) { var model = _service.FindById(id); return View(model); } [HttpPost] public ActionResult Edit(BookDetails book) { try { _service.UpdateBookDetails(book); return RedirectToAction("Index"); } catch { return View(); } } public ActionResult Delete(int id) { var model = _service.FindById(id); return View(model); } [HttpPost] public ActionResult Delete(BookDetails book) { try { _service.DeleteBookDetail(book.BookSerialNo); return RedirectToAction("Index"); } catch { return View(); } } }
Index.cshtml
@model IEnumerable<RepoDB.Models.BookDetails> @{ ViewBag.Title = "Index"; } <br /> <p> @Html.ActionLink("Create New", "Create", null, new { @class = "btn btn-primary" }) </p> <div class="table-responsive"> <table id="tblBooks" class="table table-bordered table-condensed table-striped"> <tr> <th> @Html.Label("ISBN") </th> <th> @Html.Label("Title") </th> <th> @Html.Label("Author") </th> <th> @Html.Label("Publisher") </th> <th> @Html.Label("Category") </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.BookISBN) </td> <td> @Html.DisplayFor(modelItem => item.BookTitle) </td> <td> @Html.DisplayFor(modelItem => item.BookAuthor) </td> <td> @Html.DisplayFor(modelItem => item.BookPublisher) </td> <td> @Html.DisplayFor(modelItem => item.BookCategory) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.BookSerialNo }, new { @class = "btn btn-info" }) @Html.ActionLink("Delete", "Delete", new { id = item.BookSerialNo }, new { @class = "btn btn-warning" }) </td> </tr> } </table> </div>
@model RepoDB.Models.BookDetails @{ ViewBag.Title = "Create"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>New Book</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.BookISBN, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookISBN, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookISBN, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookTitle, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookTitle, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookTitle, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookAuthor, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookAuthor, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookAuthor, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookPublisher, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookPublisher, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookPublisher, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookCategory, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookCategory, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookCategory, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-primary" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> <script src="~/Scripts/jquery-1.10.2.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
@model RepoDB.Models.BookDetails @{ ViewBag.Title = "Update"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.HiddenFor(model => model.BookSerialNo) <div class="form-horizontal"> <h4>Update Book</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.BookISBN, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookISBN, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookISBN, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookTitle, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookTitle, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookTitle, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookAuthor, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookAuthor, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookAuthor, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookPublisher, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookPublisher, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.BookPublisher, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.BookCategory, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.BookCategory, new { htmlAttributes = new { @class = "form-control"} }) @Html.ValidationMessageFor(model => model.BookCategory, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-primary" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> <script src="~/Scripts/jquery-1.10.2.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
@model RepoDB.Models.BookDetails @{ ViewBag.Title = "Delete"; } <h3>Are you sure you want to delete this record?</h3> <div> <hr /> <dl class="dl-horizontal"> <dt> @Html.DisplayNameFor(model => model.BookISBN) </dt> <dd> @Html.DisplayFor(model => model.BookISBN) </dd> <dt> @Html.DisplayNameFor(model => model.BookTitle) </dt> <dd> @Html.DisplayFor(model => model.BookTitle) </dd> <dt> @Html.DisplayNameFor(model => model.BookAuthor) </dt> <dd> @Html.DisplayFor(model => model.BookAuthor) </dd> <dt> @Html.DisplayNameFor(model => model.BookPublisher) </dt> <dd> @Html.DisplayFor(model => model.BookPublisher) </dd> <dt> @Html.DisplayNameFor(model => model.BookCategory) </dt> <dd> @Html.DisplayFor(model => model.BookCategory) </dd> </dl> @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.HiddenFor(model => model.BookSerialNo) <div class="form-actions no-color"> @Html.ActionLink("Back to List", "Index", null, new { @class = "btn btn-primary" }) <input type="submit" value="Delete" class="btn btn-danger" /> </div> } </div>
Happy coding!
Comments
Post a Comment