【C#/.NET】Dapper使用QueryMultipleAsync執行多條SQL

2023-06-09 18:00:44

 目錄

 

背景

解決方案

總結


 

背景

        對於查詢資料列表的功能,需要分頁已經查詢總數。這裡涉及兩句SQL,一個是查詢分頁對應的資料,第二個是Count(*); 會導致部分重複程式碼和兩次的資料庫查詢。

 

解決方案

        Dapper有封裝QueryMultipleAsync的非同步方法支援執行多條SQL,來減少資料庫查詢次數。

使用方法

 public async Task<(IEnumerable<Log> list,int total)> GetListAsync()
    {
        string sql = @"SELECT sql_calc_found_rows id, mark1, mark2, mark3  
                       FROM logs ORDER BY id ASC  LIMIT @Offset, @PageSize;
                       SELECT FOUND_ROWS()  ";
        DynamicParameters parameters = new DynamicParameters();
        parameters.Add("@Offset", 0);
        parameters.Add("@PageSize", 2);

        using var connection = _dapperContext.CreateConnection();
        using var multi = await connection.QueryMultipleAsync(sql, parameters);
        var list = await multi.ReadAsync<Log>();
        var total = await multi.ReadSingleAsync<int>();
        return (list, total);
    }

 

        這裡是查詢MYSQL,使用了sql_calc_found_rows在第一個查詢分頁資料的SQL中,第二條是SELECT FOUND_ROWS()來獲取Limit之外的行數。

        使用QueryMultipleAsync方法返回的是一個GridReader物件。這個物件提供了一些方法讀取資料,比如

ReadReadAsync 返回可列舉的動態型別
Read<T>ReadAsync<T> 返回 T 引數指定型別的列舉
ReadFirstReadFirstAsync Returns the first row as a dynamic type
ReadFirst<T>ReadFirstAsync<T> 將第一行作為動態型別返回
ReadFirstOrDefaultReadFirstOrDefaultAsync 返回第一行作為 T 型別引數指定型別的範例
ReadFirstOrDefault<T>ReadFirstOrDefaultAsync<T> 將第一行作為動態型別返回,如果未返回任何結果,則返回 null
ReadSingleReadSingleAsync 返回第一行作為 T 型別引數指定型別的範例,如果沒有返回結果則返回 null
ReadSingle<T>ReadSingleAsync<T> 在預期只返回一行時使用。 返回動態型別
ReadSingleOrDefaultReadSingleOrDefaultAsync 在預期返回零行或一行時使用。 返回動態型別或 null
 

        範例中使用ReadAsync讀取資料,ReadSingleAsync讀取count然後返回元組

var list = await multi.ReadAsync<Log>();
var total = await multi.ReadSingleAsync<int>();
return (list, total);

總結

        通過使用Dapper的QueryMultipleAsync一次性查詢多個結果,減少了與資料庫伺服器的請求次數。減少了程式碼量。