Dapper 是一个 容易上手,轻量级,灵活高效,开源的 迷你 ORM,由 Stack Overflow 团队的 Sam Saffron 出品,你可以利用 Dapper 简化数据访问并且支持高性能, 还有一点, Dapper 提供了很多异步方法,本篇我们就来聊一聊如何在 ASP.NET Core 中使用 Dapper 的异步方法。

安装 Dapper

可以通过 Visual Studio 2019 IDE 中的 NuGet package manager 可视化界面安装,也可以在 .NET CLI 命令行中输入以下命令。


dotnet add package Install-Package Dapper

一旦 package 成功安装到你的项目中,接下来就可以正式使用了。

使用异步方法

Dapper提供了几个异步方法,可用于异步的执行 CURD 操作,下面是 Dapper 的异步方法清单。

  • ExecuteAsync
  • QueryAsync
  • QueryFirstAsync
  • QueryFirstOrDefaultAsync
  • QuerySingleAsync
  • QuerySingleOrDefaultAsync
  • QueryMultipleAsync

为了演示目的,我就使用前两个异步方法进行演示。

QueryAsync 和 ExecuteAsync

创建一个 Author 实体类


    public class Author
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
    }

接下来创建一个 IAuthorRepository 接口


    public interface IAuthorRepository
    {
        Task<Author> GetByID(int id);
        public Task<bool> Insert(Author model);
    }

有了接口,就可以定义一个类实现这个接口


    public class AuthorRepository
    {
        private readonly IConfiguration _config;

        public AuthorRepository(IConfiguration config)
        {
            _config = config;
        }
        public async Task<Author> GetByID(int id)
        {
            using (IDbConnection conn = new SqlConnection(_config.GetConnectionString("IDGDbConnectionString")))
            {
                string query = "SELECT Id, FirstName, LastName,Address FROM Author WHERE Id = @id";
                conn.Open();
                var result = await conn.QueryAsync<Author>(
                query, new { Id = id });
                return result.FirstOrDefault();
            }
        }
        public async Task<bool> Insert(Author model)
        {
            return false;
        }
    }

值得注意的是上面我用了 QueryAsync 方法实现了对 SqlServer 的异步查询,接下来再填充一下 异步方法 Insert。


public async Task<bool> Insert(Author model)
{
      int x = -1;
      using (var connection = new SqlConnection(_config.GetConnectionString("IDGDbConnectionString")))
      {
          await connection.OpenAsync();
          var sqlStatement = @"INSERT INTO Author (FirstName, LastName, Address)";
          x = await connection.ExecuteAsync(sqlStatement, model);
      }
      
      return x > 0;
}

可以看到 ExecuteAsync 方法接收两个参数,一个是 sql,一个是 待插入或者更新 的数据。

对数据库连接进行依赖注入

可以将连接数据库的 ConnectionString 放到 appSettings.json 文件中,然后使用 IConfiguration 实例下的 GetConnectionString() 方法来获取 ConenctionString。

接下来,使用依赖注入机制将 IConfiguration 实例注入到 AuthorRepository 中,如下代码所示:


public class AuthorRepository : IAuthorRepository
{
    private readonly IConfiguration _config;
    public EmployeeRepository(IConfiguration config)
    {
        _config = config;
    }
    //Other methods
}

下面的代码片段展示了如何去创建 SqlConnection 实例。


    public IDbConnection DbConnection
    {
        get
        {
            return new SqlConnection(_config.GetConnectionString("IDGDbConnectionString"));
        }
    }

现在这个 DbConnection 属性就可以替代之前 Insert 方法中使用的 SqlConnection 创建的数据库连接,改造后的 Insert 方法如下。


public async Task<bool> Insert(Author model)
 {
      int x = -1;
      using (var connection = DbConnection)
      {
          await connection.OpenAsync();
          var sqlStatement = @"INSERT INTO Author (FirstName, LastName, Address)";
          x = await connection.ExecuteAsync(sqlStatement, model);
      }
      
      return x > 0;
 }

将 repository 添加到 IOC 容器中

为了后续的 依赖注入,这里先把 repository 添加到 IOC 中。


    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IAuthorRepository , AuthorRepository>();
        //Other code
    }

在 Controller 中使用 repository

接下来通过依赖注入的方式将 IAuthorRepository 实例注入到 AuthorController 中,下面的代码片段展示了如何去实现。


[Route("api/[controller]")]
[ApiController]
public class AuthorController : ControllerBase
{
    private readonly IAuthorRepository _authorRepository;
    public AuthorController(IAuthorRepository authorRepository)
    {
        _authorRepository = authorRepository;
    }
  //Action methods
}

接下来看一下 Action 中如何通过 AuthorRepository 实例来获取 Author 实例数据的。


[HttpGet]
[Route("{id}")]
public async Task<ActionResult<Author>> GetByID(int id)
{
    return await _authorRepository.GetByID(id);
}

这就是本篇的所有内容,对了,如果你想使用 Dapper 实现更高级的查询,可以研究一下 DapperExtensions ,可参考 github:https://github.com/tmsmith/Da...

译文链接:https://www.infoworld.com/art...

更多高质量干货:参见我的 GitHub: csharptranslate


一线码农
366 声望1.6k 粉丝