在Asp.net core 中 使用Dapper 和Repository Pattern模式开发WEB程序

文章讲述了在asp.netcore中使用Dapper连接SQLServer数据库,通过RepositoryPattern和UnitOfWork进行数据操作,适合初学者了解基础架构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这篇文章中,我会使用ASP.NET Core中的Dapper来连接并读取sqlserver数据库的表,并展示其数据。我会用Repository Pattern仓储模式和Unit Of Work单元测试。看完这篇文章,相信你能明白asp.net core是如何使用Dapper和仓储模式进行工作的。

首先介绍一下Dapper:

        Dapper是一个简单的对象映射框架或Micro ORM,它可以帮助我们有效地将数据从SQL查询的结果映射到.NET类,使用方法也非常简单,只需使用SQL客户端对象执行SQL Select语句,并将结果作为映射到C#的相应类并返回结果即可。与EF实体框架的性能相比,它在查询数据方面肯定更快,这在Dapper官方有专门的测试数据进行比较得出来的。因为Dapper直接使用RAW SQL,因此时间延迟非常小,从而提高了Dapper读取和写入的性能。

数据库选择并创建:

        数据库我在这里选择MSSQLSERVER 2019,在我的WIN10上安装非常方便,基本没有遇到任何问题。安装过程在这里就不介绍了。安装完成后重新启动计算机。我们使用官方的管理器SQL Server Management Studio (SSMS) 19.1  icon-default.png?t=N7T8https://aka.ms/ssmsfullsetup

进入并建立我们的测试数据库BookManager

接下来,我们在数据库中建立一个Book表,BookId为自增主键,其余字段看下图所示设置

现在,我们启动vs2022建立asp.net core mvc的项目,名称为BookTest,框架选择.net core3.1,并启用Razor运行时编译,好处是运行后我们可以在后台修改chtml代码,在前台刷新即可看到修改后的结果。

接下来,我们来创建一个类库项目,名称为BookCore

建立好后,我们在这个类库中建立Entities文件夹,并且在这个目录中建立Book图书类基本模型

    public class Book
    {
        public int BookId { get; set; }
        public string BookAuthorName { get; set; }
        public string BookDescription { get; set; }
        public decimal BookPrice { get; set; }
        public string BookTitle { get; set; }
        public DateTime BookAddedOn { get; set; }
        public DateTime BookModifiedOn { get; set; }
    }

在这里,我们建立BookCore类库的目的是把所有关于数据处理的东西都放在这里,通用性很强,便于移植,修改,好处多多的。无论你前端展示是WEB还是WINFORM都可以使用的。

下面,我们再新建一个Interface目录,并新建一个接口仓储类:

代码如下:我们在这里定义了基本的增,删,改,查操作

    public interface IRepository<T> where T : class
    {
        Task<T> GetById(int id);
        Task<IReadOnlyList<T>> GetAll();
        Task<int> Add(T entity);
        Task<int> Update(T entity);
        Task<int> Delete(int id);
    }

现在,通过建立这些我们定义的通用接口后,我们再定义一个新接口并将其命名为IBookRepository,并且将它继承以T为图书的IRepository通用接口,听起来好象有点不好理解,看图就好啦,这个接口中不用定义方法和属性。

看图中所示,要注意的是,不要忘记引用Entities。接下来,我们在接口目录下再建一个IUnitOfWork接口文件。

    public interface IUnitOfWork
    {
        IBookRepository BookRepository { get; }
    }

好了,现在,基本东西我们已添加完成,现在我们,修改BookMvcTest项目下的Web.config文件,并添加数据库连接字符串:

现在,我们在BookCore项目中在新增一个Repositories仓储目录,在这个目录中建立对实体文件的读写操作。建立完成后,我们需要通过nuget包管理器安装相应的依赖库。分别是

Install-Package Dapper
Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.DependencyInjection.Abstractions
Install-Package System.Data.SqlClient

好了,依赖包安装完成,我们来建立BookRepository类并实现图书类的接口操作

实现的代码直接在下面的源代码中复制过去就可以了。

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BookCore.Entities;
using BookCore.Interface;
using Microsoft.Extensions.Configuration;
using Dapper;
namespace BookCore.Repositories
{
    public class BookRepository : IBookRepository
    {
        private readonly IConfiguration configuration;
        public BookRepository(IConfiguration configuration)
        {
            this.configuration = configuration;
        }
        public async Task<int> Add(Book entity)
        {
            entity.BookAddedOn = DateTime.Now;
            var sql = "Insert into Products (BookAuthorName,BookDescription,BookPrice,BookTitle,BookAddedOn,BookModifiedOn) VALUES (@BookAuthorName,@BookDescription,@BookPrice,@BookPrice,@BookAddedOn,BookModifiedOn)";
            using (var connection = new SqlConnection(configuration.GetConnectionString("DbConnectionString")))
            {
                connection.Open();
                var result = await connection.ExecuteAsync(sql, entity);
                return result;
            }
        }
        public async Task<int> Delete(int id)
        {
            var sql = "DELETE FROM Products WHERE BookId = @BookId";
            using (var connection = new SqlConnection(configuration.GetConnectionString("DbConnectionString")))
            {
                connection.Open();
                var result = await connection.ExecuteAsync(sql, new { BookId = id });
                return result;
            }
        }
        public async Task<IReadOnlyList<Book>> GetAll()
        {
            var sql = "SELECT * FROM Products";
            using (var connection = new SqlConnection(configuration.GetConnectionString("DbConnectionString")))
            {
                connection.Open();
                var result = await connection.QueryAsync<Book>(sql);
                return result.ToList();
            }
        }
        public async Task<Book> GetById(int id)
        {
            var sql = "SELECT * FROM Products WHERE BookId = @Id";
            using (var connection = new SqlConnection(configuration.GetConnectionString("DbConnectionString")))
            {
                connection.Open();
                var result = await connection.QuerySingleOrDefaultAsync<Book>(sql, new { Id = id });
                return result;
            }
        }
        public async Task<int> Update(Book entity)
        {
            entity.BookModifiedOn = DateTime.Now;
            var sql = "UPDATE Books SET BookAuthorName = @BookAuthorName, BookDescription = @BookDescription, BookPrice = @BookPrice, BookTitle = @BookTitle, BookModifiedOn = @BookModifiedOn  WHERE BookId = @Id";
            using (var connection = new SqlConnection(configuration.GetConnectionString("DbConnectionString")))
            {
                connection.Open();
                var result = await connection.ExecuteAsync(sql, entity);
                return result;
            }
        }
    }
}

在这个程序中,我们首先将连接字符串从web.config中取出来,使用IConfiguration接口使连接字符串可以在我们的整个应用程序中使用。将IConfiguration注入到BookRepository的构造函数就可以了。增删改查的方法利用Dapper很容易实现,记住别忘记添加引用哦。

接下来,我们再来建立UnitOfWork并实现相应的接口

写到这里,发现了一个问题,就是最开始建立的BookMvcTest项目不是.net core,而是.net framework 4.72,好吧,很简单,删除掉,重新建一个UI展示项目就可以了,因为重要的工作基本都在BookCore中完成了。其中,.net core中的连接字符串文件是appsettings.json,需要重新修改一下。

再修改启动文件,添加注入。接着在BookCore项目的Repository目录中建立一个服务注册类,这是一个静态类,作用是把需要的仓储和接口实现进行服务注册。类名为ServiceRegistration。

接下来比较重要的一步,修改BookMvcTest目录下的Startup.cs文件,并将刚才类进行注册服务。

好了,到这里基本的东西就差不多了,其余的就是新建一个Book控制器,然后调用相应的类读取数据,这里也写一下吧。

我们新建一个Book控制器

在这个BookController控制器,通过构造函数来实现对Modes的一系列的操作。

控制器里的代码直接拷上来吧。

using System;
using System.Threading.Tasks;
using BookCore.Entities;
using BookCore.Interface;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace BookMvcTest.Controllers
{
    public class BookController : Controller
    {
        private IBookRepository _bookRepository;

        public BookController(IBookRepository bookRepository)
        {
            _bookRepository=bookRepository;
        }
        // GET: BookController
        public async Task<ActionResult> Index()
        {
            var data = await _bookRepository.GetAll();
            return View(data);
        }

        // GET: BookController/Details/5
        public async Task<ActionResult> Details(int id)
        {
            var data = await _bookRepository.GetById(id);
            return View(data);
        }

        [HttpPost]
        public async Task<ActionResult> Create(Book book)
        {
            var data = await _bookRepository.Add(book);
            return Redirect("Index");
        }


        // GET: BookController/Edit/5
        public async Task<ActionResult> Edit(int id)
        {
            var data= await _bookRepository.GetById(id);
            return View(data);
        }

        // POST: BookController/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit(int id, IFormCollection collection)
        {
            var data = await _bookRepository.GetById(id);
            data.BookTitle = collection["title"];
            data.BookDescription = collection["description"];
            data.BookAuthorName = collection["authorname"];
            data.BookPrice = Convert.ToDecimal(collection["price"]);
            try
            {
                await _bookRepository.Update(data);
                return RedirectToAction(nameof(Index));
            }
            catch
            {
                return View();
            }
        }

        [HttpPost]
        public async Task<ActionResult> Delete(int id)
        {
            var data=await _bookRepository.Delete(id);
            return Redirect("Index");
        }


    }
}

好了,到这里基本就完成了,至于添加视图页面,太简单了,这里就不一一写出来了,有需要的小伙伴可以给我留言。哪里有不明白的地方,我们可以互相学习讨论哦。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caifox菜狐狸

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值