Using ASP.NET Core3.1 and Dapper, I want to insert a record to my database and get the whole table as result ! Currently I have two queries in my repository
as below:
First: to insert a record to my data base:
//some codes here
string sql = "UPDATE likes AS L SET L.isLike = @isLikeSQL WHERE L.ItemId = @ItemIdSQL AND L.Ip = @IpSQL ";
await dbConnection.ExecuteAsync(sql, new { ItemIdSQL = ItemId, senderpSQL = Ip, isLikeSQL = isLike });
Second: To get the whole table after inserting the top record:
//some codes here
string sql = " SELECT COUNT(*) FROM likes AS I WHERE I.ItemId = @itemIdSQL AND I.isLike=1; " +
" SELECT COUNT(*) FROM map118.likes AS I WHERE I.ItemId = @itemIdSQL AND I.isLike=0; ";
using (var data = await dbConnection.QueryMultipleAsync(sql, new { itemIdSQL = ItemId }))
{
numberOfLikes = data.Read<int>().FirstOrDefault();
numberOfDislikes = data.Read<int>().FirstOrDefault();
}
I need to know if I can have all above in one query by dapper !! In fact we have QueryMultipleAsync
in dapper that can manage more than one query ( AS I have done myself ) but I do not know if we can merge an ExecuteAsync
and QueryAsync
and have them all in one query for better performance. I need something like this :
string sql =
"UPDATE likes AS L SET L.isLike = @isLikeSQL WHERE L.ItemId = @ItemIdSQL AND L.Ip = @IpSQL " +
" SELECT COUNT(*) FROM likes AS I WHERE I.ItemId = @itemIdSQL AND L.isLike=1; "
using (var data = await dbConnection.QueryOrExecute???(sql, new { itemIdSQL = ItemId }))
{
numberOfLikes = data.Read<int>().FirstOrDefault();
numberOfDislikes = data.Read<int>().FirstOrDefault();
}
UPDATE
doesn't return a grid (unless you are using the OUTPUT
clause. You can do as many operations as you like in a SQL operation - all that Dapper cares about is the result grids, so yes, you can perform an update
and (separately) a select
. The only significance of Execute
over Query
is that Execute
expects zero grids. If you're returning a single grid, then Query
; if you're returning multiple grids: QueryMultiple
. Dapper has no interest in what happens inside the query - it is entirely opaque - all it sees is result grids.
I highly recommend using the formal operation separator (;
), though. For example:
const string sql = @"
UPDATE likes AS L
SET L.isLike = @isLike
WHERE L.ItemId = @ItemId AND L.Ip = @Ip;
SELECT COUNT(*) FROM likes AS I WHERE I.ItemId = @ItemId AND L.isLike=1;
SELECT COUNT(*) FROM likes AS I WHERE I.ItemId = @ItemId AND L.isLike=0;
"
using (var data = await dbConnection.QueryMultipleAsync(sql,
new { ItemId, isLike, Ip }))
{
numberOfLikes = data.ReadSingle<int>();
numberOfDislikes = data.ReadSingle<int>();
}
although to be honest I might be tempted to do, instead, a single final select
, using Dapper's positional treatment of value-tuples:
const string sql = @"
UPDATE likes AS L
SET L.isLike = @isLike
WHERE L.ItemId = @ItemId AND L.Ip = @Ip;
SELECT
(SELECT COUNT(*) FROM likes AS I WHERE I.ItemId = @ItemId AND L.isLike=1),
(SELECT COUNT(*) FROM likes AS I WHERE I.ItemId = @ItemId AND L.isLike=0);
"
(var numberOfLikes, var numberOfDislikes) =
await dbConnection.QuerySingleAsync<(int,int)>(sql,
new { ItemId, isLike, Ip });
or something involving group by L.isLike