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();
}
If your project prefers writing stored procedures or writing native query instead of using a full-fledged ORM tools like EntityFramework or NHibernate then Dapper is obvious choice for you. Using Dapper, it is very easy to fire a SQL query against database and get the result mapped to C# domain class.
Dapper is an object–relational mapping (ORM) product for the Microsoft .
Dapper is super awesome to handle complex queries that sport multiple joins and some real long business logic. Entity Framework Core is great for class generation, object tracking, mapping to multiple nested classes, and quite a lot more.
Dapper is a simple Object Mapping Framework or a Micro-ORM that helps us to Map the Data from the Result of an SQL Query to a . NET Class efficiently. It would be as simple as executing a SQL Select Statement using the SQL Client object and returning the result as a Mapped Domain C# Class.
After some digging, I was able to find a cause:
Below is CreateParamInfoGenerator delegate from dapper's SqlMapper:
public static Action<IDbCommand, object> CreateParamInfoGenerator(Identity identity)
{
// code above here
IEnumerable<PropertyInfo> props = type.GetProperties().OrderBy(p => p.Name);
The props is your unanimous param which gets re-ordered by OrderBy(p => p.Name), which moves city upfront.
new { firstName = "John", city = "SomeCity", lastName = "Smith" }
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:
var parameters = new DynamicParameters();
parameters.Add("city", "SomeCity");
parameters.Add("firstName", "John");
parameters.Add("lastName", "Smith");
var result = dbConnection.Query<string>(
"update Students set FirstName = @firstName, City = @city where LastName = @lastName",
parameters
);
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
public void Update(Movie movie)
{
var sql = "UPDATE myDB.movies set title=@param1, genre=@param2 where ID=@param3";
db.Execute(sql, new { param1 = movie.Title, param2 = movie.Genre, param3 = movie.ID });
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With