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

Tre*_*rev 9 c# oledb ado.net ms-access dapper

让我们首先解决这个问题:我使用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();
}
Run Code Online (Sandbox Code Playgroud)

这很好用:

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();
}
Run Code Online (Sandbox Code Playgroud)

这不会......它执行时没有错误,但它将FirstName设置为DB中的"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();
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

编辑以下

如果我使用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();
}
Run Code Online (Sandbox Code Playgroud)

Voi*_*Ray 9

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

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

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

        // code above here
        IEnumerable<PropertyInfo> props = type.GetProperties().OrderBy(p => p.Name); 
Run Code Online (Sandbox Code Playgroud)

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

new { firstName = "John", city = "SomeCity", lastName = "Smith" }
Run Code Online (Sandbox Code Playgroud)

然后将道具添加到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
        );
Run Code Online (Sandbox Code Playgroud)

以上没有用,所以属性的顺序是原因!

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

希望这可以帮助.