9

让我们从解决这个问题开始:我被困在使用 MS Access DB 并且无法更改它。

这工作正常:

using (OleDbConnection conn = ConnectionHelper.GetConnection())
{
  conn.Open();
  var results = conn.Query<string>(
    "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 设置为“SomeCity”,将 City 设置为“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();
}

有任何想法吗?

在下面编辑

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

2 回答 2

9

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

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

    public static Action<IDbCommand, object> CreateParamInfoGenerator(Identity identity)
    {

        // code above here
        IEnumerable<PropertyInfo> 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<string>(
          "update Students set FirstName = @firstName, City = @city where LastName = @lastName",
          parameters
        );

上面的也不起作用,所以属性的顺序就是原因!

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

希望这可以帮助。

于 2012-09-08T01:08:25.830 回答
4

我有一个类似的问题,我所做的是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 });
}
于 2014-01-29T07:03:35.550 回答