DapperLib / Dapper

Dapper - a simple object mapper for .Net
https://www.learndapper.com/
Other
17.29k stars 3.67k forks source link

Issue with Dapper: Intermittent '@ParameterNames1 is not a parameter for procedure...' Error #2091

Open hohoan opened 4 weeks ago

hohoan commented 4 weeks ago

Hello,

I'm encountering an intermittent issue with Dapper. Occasionally, I receive the error message '@ParameterNames1 is not a parameter for procedure....' When I stop and restart the application using 'dotnet run', the error disappears, and everything works fine. However, after a while, the error reappears.

I've thoroughly checked the parameters I'm passing, and they are correct because the application runs without issues after restarting.

Could you please help me troubleshoot this issue?

Thank you.

P/s: Dapper 2.1.44 and .Net 8.0

``

        using var con = new SqlConnection(_connectionString);
        const string sql = "TestStore";
        DynamicParameters para = new();
        para.Add("@type", 1);
        para.Add("@employeeID", employeeID);

        var result = await con.QueryAsync<object>(sql, para, commandType: CommandType.StoredProcedure);
mgravell commented 4 weeks ago

Does any part of your code use something akin to ParameterNames ? Also: note that DynamicParameters is not needed here - a new { type = 1, employeeId } would be more efficient

hohoan commented 3 weeks ago

Thanks for replying.

I used 'new {type = 1, employeeId}' and didn't get that error. I'm continuing to monitor to see if there are any other issues.

Wintekso commented 2 weeks ago

Greetings,

First off thank you dapper team for providing this library.

We have also experienced this when using QueryAsync against a stored procedure and dynamic parameters passed. The sql profiler shows the correct exec sp_test @Id = 'guid'

Until randomly it will show exec sp_test @ParameterNames1=N'Id' etc which causes the failure.

For anyone else experiencing the specific issue (@ParameterNames1 is not a parameter for procedure), we found the QueryMultiple functions work every time so we have moved to using this with stored procedures returning results.

example of changing to querymultiple:

    var result = await connection.QueryAsync<TDbItem>(StoredProcedureName, parameters, commandType: CommandType.StoredProcedure);
    return result;

to

    var queryResult = await connection.QueryMultipleAsync(StoredProcedureName, parameters, commandType: CommandType.StoredProcedure);
    return await queryResult.ReadAsync<TDbItem>();

Hope that helps

Many thanks

mgravell commented 2 weeks ago

This sounds very odd; I wonder whether there is some kind of internal strategy cache conflict happening here. I'll take a look at that, but as a side note: you could try using AOT mode - there is no strategy cache in the AOT implementation, so: nothing to get conflicted on; you can try this via: https://aot.dapperlib.dev/gettingstarted.html