【问题标题】:Dapper & MS Access - Read works, Write doesn'tDapper & MS Access - 读取有效,写入无效
【发布时间】:2012-09-01 13:38:45
【问题描述】:

让我们首先解决这个问题:我被困在使用 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();
}

【问题讨论】:

  • 这很奇怪..我需要尝试重现...
  • 注意:刚刚尝试使用 sql express 2008 进行复制,它工作正常...
  • @Trev 有趣;我将不得不检查
  • 根据对答案here的评论,这不再是当前版本的Dapper的问题。
  • @RobinAtTech - 感谢您的更新。我似乎记得测试了 Dapper 本身的后续版本,并确认它不再按名称对参数进行排序,但那是很久以前的事了,我不能再确定了。我想知道 Dapper-Extensions 是否仍然按名称对参数进行排序,可能是因为它仍然与旧版本的 Dapper 相关联。 (GitHub 上的 Dapper-Extensions 已经两年多没有更新了。)

标签: c# ms-access ado.net oledb dapper


【解决方案1】:

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

下面是来自 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" }

Props 然后被添加到顺序很重要的 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 的正式判决......

希望这会有所帮助。

【讨论】:

  • 原来 MS Access 是fussy about the order of the parameters。我尝试从 SqlMapper 中删除 .OrderBy(p =&gt; p.Name) 代码,它现在可以工作了。我也想从 Marc 或 Sam 那里知道删除此代码是否会对其他地方产生任何影响。
  • 我也不知道;很高兴知道!而且我也很好奇 OrderBy() 子句的用途。
  • 根据对答案here的评论,这不再是当前版本的Dapper的问题。
  • 在 NuGet 的 1.42 版本中仍然存在此问题。
  • @Bob 这个问题还在 1.50.2 中
【解决方案2】:

我遇到了类似的问题,我所做的是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 });
}

【讨论】:

  • 自从您上次使用 Dapper 以来,情况可能已经发生了变化。根据对答案here的评论,当前版本不再是这个问题。
  • @GordThompson 感谢您的链接。我在通过 NuGet 使用 1.13 版时遇到了同样的问题。
  • 我在 1.50.2 中遇到了同样的问题
猜你喜欢
  • 2021-09-14
  • 2023-04-03
  • 2011-08-27
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多