You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1中能否通过Dapper同时执行更新与查询操作?

当然可以合并这两个操作!

Dapper完全支持在同一个数据库批处理中执行更新语句和查询语句,这样做能减少数据库往返次数,确实能提升性能——毕竟两次请求变成一次,省去了网络开销和数据库连接的额外消耗。

优化方案:合并更新与统计查询

首先,我们可以把你的两个操作合并成一段SQL,甚至可以把原来的两个COUNT查询合并成一个(减少一次表扫描,更高效)。这里用CASE WHEN来一次性统计点赞和点踩的数量:

-- 先执行更新操作
UPDATE likes AS L 
SET L.isLike = @isLikeSQL 
WHERE L.ItemId = @ItemIdSQL AND L.Ip = @IpSQL;

-- 再执行合并统计查询
SELECT 
    SUM(CASE WHEN isLike = 1 THEN 1 ELSE 0 END) AS NumberOfLikes,
    SUM(CASE WHEN isLike = 0 THEN 1 ELSE 0 END) AS NumberOfDislikes
FROM likes 
WHERE ItemId = @ItemIdSQL;

对应的Dapper代码实现

用QueryMultipleAsync就可以处理这段SQL——它不仅支持多查询,也能处理包含更新/插入/删除语句的批处理,只要后面有SELECT返回结果集即可:

// 注意修正你原代码里的参数笔误:senderpSQL → IpSQL
var parameters = new { 
    ItemIdSQL = ItemId, 
    IpSQL = Ip, 
    isLikeSQL = isLike 
};

string sql = @"
UPDATE likes AS L 
SET L.isLike = @isLikeSQL 
WHERE L.ItemId = @ItemIdSQL AND L.Ip = @IpSQL;

SELECT 
    SUM(CASE WHEN isLike = 1 THEN 1 ELSE 0 END) AS NumberOfLikes,
    SUM(CASE WHEN isLike = 0 THEN 1 ELSE 0 END) AS NumberOfDislikes
FROM likes 
WHERE ItemId = @ItemIdSQL;";

using (var data = await dbConnection.QueryMultipleAsync(sql, parameters))
{
    // 第一个语句是UPDATE,没有结果集,直接读取第二个查询的统计结果
    var countResult = data.Read<(int NumberOfLikes, int NumberOfDislikes)>().FirstOrDefault();
    numberOfLikes = countResult.NumberOfLikes;
    numberOfDislikes = countResult.NumberOfDislikes;
}

额外进阶:获取更新受影响行数

如果你需要知道这次更新操作影响了多少行数据(比如判断用户之前是否已经点赞/点踩过),可以在UPDATE后加一行获取受影响行数的语句(不同数据库语法略有差异):

  • SQL Server:SELECT @@ROWCOUNT;
  • MySQL:SELECT ROW_COUNT();
  • PostgreSQL:GET DIAGNOSTICS row_count = ROW_COUNT; SELECT row_count;

以SQL Server为例,修改后的SQL:

UPDATE likes AS L 
SET L.isLike = @isLikeSQL 
WHERE L.ItemId = @ItemIdSQL AND L.Ip = @IpSQL;
SELECT @@ROWCOUNT; -- 获取更新受影响的行数

SELECT 
    SUM(CASE WHEN isLike = 1 THEN 1 ELSE 0 END) AS NumberOfLikes,
    SUM(CASE WHEN isLike = 0 THEN 1 ELSE 0 END) AS NumberOfDislikes
FROM likes 
WHERE ItemId = @ItemIdSQL;

对应的代码:

using (var data = await dbConnection.QueryMultipleAsync(sql, parameters))
{
    int rowsAffected = data.Read<int>().FirstOrDefault();
    var countResult = data.Read<(int NumberOfLikes, int NumberOfDislikes)>().FirstOrDefault();
    
    // 可以根据rowsAffected判断是否是首次操作:比如0表示用户之前没有该记录
    if (rowsAffected == 0)
    {
        // 可选逻辑:如果用户没有点赞/点踩记录,可能需要插入一条新记录?
    }
    
    numberOfLikes = countResult.NumberOfLikes;
    numberOfDislikes = countResult.NumberOfDislikes;
}

注意事项

  • 确保你的数据库支持批处理SQL(主流数据库如SQL Server、MySQL、PostgreSQL都支持);
  • 如果你需要严格保证更新和查询的一致性(比如高并发场景),可以在操作外面加上事务:using (var transaction = await dbConnection.BeginTransactionAsync()),然后把transaction传给QueryMultipleAsync的参数;
  • 原代码里的参数名senderpSQL应该是笔误,改成了IpSQL,注意对应上参数名。

内容的提问来源于stack exchange,提问作者ehsan_kabiri_33

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:32:49