Let's start by getting this out of the way: I'm stuck using an MS Access DB and I can't change it.
This works fine:
using (OleDbConnection conn = ConnectionHelper.GetConnection())
{
conn.Open();
var results = conn.Query<string>(
"select FirstName from Students where LastName = @lastName",
new { lastName= "Smith" }
);
conn.Close();
}
This works fine:
using (OleDbConnection conn = ConnectionHelper.GetConnection())
{
OleDbCommand cmd = new OleDbCommand(
"update Students set FirstName = @firstName, City = @city where LastName = @lastName",
conn
);
cmd.Parameters.AddWithValue("firstName", "John");
cmd.Parameters.AddWithValue("city", "SomeCity");
cmd.Parameters.AddWithValue("lastName", "Smith");
conn.Open();
var result = cmd.ExecuteNonQuery();
conn.Close();
}
This doesn't... it executes without error but it sets the FirstName as "SomeCity" in the DB and the City as "John":
using (OleDbConnection conn = ConnectionHelper.GetConnection())
{
conn.Open();
var results = conn.Query<string>(
"update Students set FirstName = @firstName, City = @city where LastName = @lastName",
new { firstName = "John", city = "SomeCity", lastName = "Smith" }
);
conn.Close();
}
Any ideas?
EDIT BELOW
Dapper works if I use DynamicParameters:
using (OleDbConnection conn = ConnectionHelper.GetConnection())
{
DynamicParameters parameters = new DynamicParameters();
parameters.Add("firstName", "John");
parameters.Add("city", "SomeCity");
parameters.Add("lastName", "Smith");
conn.Open();
var result = conn.Query<string>(
"update Students set FirstName = @firstName, City = @city where LastName = @lastName",
parameters
);
conn.Close();
}
After some digging, I was able to find a cause:
Below is CreateParamInfoGenerator delegate from dapper's SqlMapper:
The props is your unanimous param which gets re-ordered by OrderBy(p => p.Name), which moves city upfront.
Props is then being added to the IDbCommand Parameters where the order is important.
If I comment out OrderBy() clause, then everything works.
I also tested DynamicParameters and intentionally re-ordered the attributes to move city upfront:
The above did not work as well, so the order of attributes is the reason!
I guess you can modify your local copy of SqlMapper for now and remove OrderBy() and wait for an official verdict from Marc...
Hope this helps.
I had a similar issue, what I did was to
use parameter names like @param1, @param2
instead of @name,@id,@price so the order stays the same without having to modify SQLMapper.cs file.Something like