Dapper和MS Access – 读取工作,写入不起作用

让我们首先解决这个问题:我使用MS Access DB时遇到困难,我无法改变它。

这很好用:

using (OleDbConnection conn = ConnectionHelper.GetConnection()) { conn.Open(); var results = conn.Query( "select FirstName from Students where LastName = @lastName", new { lastName= "Smith" } ); conn.Close(); } 

这很好用:

 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(); } 

这不会……它执行时没有错误,但它将FirstName设置为DB中的“SomeCity”,将City设置为“John”:

 using (OleDbConnection conn = ConnectionHelper.GetConnection()) { conn.Open(); var results = conn.Query( "update Students set FirstName = @firstName, City = @city where LastName = @lastName", new { firstName = "John", city = "SomeCity", lastName = "Smith" } ); conn.Close(); } 

有任何想法吗?

编辑以下

如果我使用DynamicParameters,Dapper可以工作:

 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( "update Students set FirstName = @firstName, City = @city where LastName = @lastName", parameters ); conn.Close(); } 

经过一番挖掘,我找到了一个原因:

下面是来自dapper的SqlMapper的CreateParamInfoGenerator委托:

  public static Action CreateParamInfoGenerator(Identity identity) { // code above here IEnumerable props = type.GetProperties().OrderBy(p => p.Name); 

道具是你的一致参数,由OrderBy(p => p.Name)重新排序,它可以提前移动城市。

 new { firstName = "John", city = "SomeCity", lastName = "Smith" } 

然后将道具添加到IDbCommand参数中,其中订单很重要。

如果我注释掉OrderBy()子句,那么一切正常。

我还测试了DynamicParameters并故意重新排序属性以提前移动城市:

  var parameters = new DynamicParameters(); parameters.Add("city", "SomeCity"); parameters.Add("firstName", "John"); parameters.Add("lastName", "Smith"); var result = dbConnection.Query( "update Students set FirstName = @firstName, City = @city where LastName = @lastName", parameters ); 

上面的方法也不行,所以属性的顺序就是原因!

我想你现在可以修改你的SqlMapper的本地副本并删除OrderBy()并等待Marc的官方判决……

希望这可以帮助。

我有一个类似的问题,我做的是use parameter names like @param1, @param2而不是@ name,@ id,@ price,所以顺序保持不变,而不必修改SQLMapper.cs文件。

就像是

 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 }); }