3

I'm running PostgreSQL 15 and added both Dapper and Npgsql 7.0 to my project. I need to run the following function:

CREATE OR REPLACE FUNCTION get_all_posts(
    start_date date default null,
    end_date date default null,
    user_id integer default null,
    take_rows integer default 10,
    skip_rows integer default 0)
 RETURNS SETOF post_info
 LANGUAGE plpgsql
AS $function$
BEGIN
    RETURN QUERY SELECT .....
END;
$function$
;

Then I tried the following piece of C# code to execute this query and return the resultset:

using (var reader = await connection.ExecuteReaderAsync("get_all_posts", 
                   new
                   {
                       start_date = postRequest.StartDate as object ?? DBNull.Value,
                       end_date = postRequest.EndDate as object ?? DBNull.Value,
                       user_id = postRequest.UserId as object ?? DBNull.Value,
                       take_rows = take,
                       skip_rows = skip,
                   }, commandType: CommandType.StoredProcedure))
{
// ...
}

This causes the error saying that get_all_posts is not a procedure (Npgsql 7.0 stopped accepting the CommandType.StoredProcedure for functions).

And then tried to use the SELECT statement like this:

using (var reader = await connection.ExecuteReaderAsync("SELECT * FROM get_all_posts($1, $2, $3, $4, $5)", 
                   new
                   {
                       start_date = postRequest.StartDate as object ?? DBNull.Value,
                       end_date = postRequest.EndDate as object ?? DBNull.Value,
                       user_id = postRequest.UserId as object ?? DBNull.Value,
                       take_rows = take,
                       skip_rows = skip,
                   }, commandType: CommandType.Text))
{
// ...
}

But in this case the error was bind message supplies 0 parameters, but prepared statement "" requires.

How's the correct way of getting Npgsql and Dapper to execute PostgreSQL function?

2 Answers 2

1

CommandType.StoredProcedure has been changed to invoke stored procedures in Npgsql 7.0, see the release notes.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer, but I know it has changed, in fact, that information is already in my question. The problem is that Npgsql in their example uses NpgCommand and parameters (internally using the index to assign the $1, $2, etc.) but I'm using Dapper and it is using anonymous object to add parameters
Dapper indeed doesn't use positional parameters ($1, $2). So simply replace those with Dapper's named placeholders, e.g. @StartDate, @EndDate (make sure to adjust the names in the anonymous object to correspond).
-1

I'm using dapper too. After 2 day, i found this solution:

AppContext.SetSwitch("Npgsql.EnableStoredProcedureCompatMode", true);

2 Comments

How does this answer the question ?
@gobes Without this, it can not find the function. Only when I use "AppContext.SetSwitch("Npgsql.EnableStoredProcedureCompatMode", true);" dapper can found and execute the postgres function. This question includes "This causes the error saying that get_all_posts is not a procedure (Npgsql 7.0 stopped accepting the CommandType.StoredProcedure for functions)." So my advice is answer for that problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.