使用Dapper写入MS Access时的OleDbException

dapper f# ms-access oledb

我正在尝试使用Dapper插入到我的MS Access数据库中,现在查询数据工作正常,但是当我尝试插入时,我得到一个System.Data.OleDb.OleDbException : Data type mismatch in criteria expression

代码是:

let conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=path;Persist Security Info=False;")

let exec f =
    try
        conn.Open()
        do f() 
    finally
        conn.Close()

[<CLIMutable>]
type Timecard =
    { Id          : int
      Employee    : string
      WorkDate    : DateTime
      Hours       : int
      Description : string
      BillType    : string }

exec (fun () -> 
        let tc = { Id = 0
                   Employee = "John Doe" 
                   WorkDate = DateTime.Today 
                   Hours = 10
                   Description = "working 9 to 5"
                   BillType = "BillableInternal" }
        conn.Execute("insert into Timecards (Employee, WorkDate, Hours, Description, BillType) values (@Employee, @WorkDate, @Hours, @Description, @BillType)", tc)             
       |> ignore)

一般承认的答案

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

下面是来自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的官方判决......

希望这可以帮助。


热门答案

我有一个类似的问题,我做的是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 });
}


许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因