3

I am simply inserting data using [c#, DAPPER, MS Access] inside a table but the column which is [DateTime] in c# is mapped to [date/time] column in MsAccess cause a issue like "data mismatch in criteria expression".

After a long research I got a link, but the "Floor" solution doesn't work here. Any suggestions are most welcome.

Community
  • 1
  • 1
Ankur Soni
  • 5,725
  • 5
  • 50
  • 81

5 Answers5

2

The best solution I found is changing the parameter syntax inside the query string from @Foo to ?Foo?.

The reason for this is explained in https://github.com/StackExchange/Dapper/issues/911

0

Try something like this which works for me:

@CLStart = DateTime.Parse(Convert.ToDateTime(client.CLStart).ToShortDateString())

client.CLStart here is of data type DateTime? - a Nullable<DateTime>

BlackICE
  • 8,816
  • 3
  • 53
  • 91
Nandy
  • 1
  • 2
0

I've had this issue before when handwriting SQL queries in combination with Dapper and MS Access when the query has multiple parameters. The problem is that the access engine doesn't respect parameter order and sorts them alphabetically.

Take for example this sample table named MyTable:

MyNumber   Number
MyDate     Date/Time

Assuming you had a C# class MyClass:

public class MyClass
{
    public int MyNumber { get; set; }
    public DateTime MyDate { get; set; }
}

And had an instance myClass that you passed into the following Dapper statement:

connection.Execute("INSERT INTO MyTable (MyNumber, MyDate) VALUES (@MyNumber, @MyDate)", myClass);

The statement would fail due to System.Data.OleDb.OleDbException: 'Data type mismatch in criteria expression.'

This is because Access will sort the parameters alphabetically, which in this case causes it to try to stick a number into a date and a date into a number.

You can workaround this by naming your parameters in an alphabetically-friendly manner, or ordering them alphabetically. In this case the above statement could be rewritten as:

connection.Execute("INSERT INTO MyTable (MyDate, MyNumber) VALUES (@MyDate, @MyNumber)", myClass);
Ondrej Balas
  • 514
  • 4
  • 6
  • After some trails, I found that it is not about access engine. It is more like the Dapper mapping your `MyClass` alphabetically to generate a DbCommand. You can try to use an anonymous object like `new {MyNumber=1,MyDate=Today}` to match the first statement, which overwriten the default alphabet order. No error will apear. It looks like Dapper's mapping reflection is somehow related to the properties' order of your entity. And try the hand coded way using `OleDbCommand`. The order depends on `cmd.Parameters.Add`. – joe Dec 26 '17 at 05:50
0

I had the same problem in vb.net, and I solved it this way.

 Public Shared Function dapperBugDate(ByVal birthday As Date)
        birthday = birthday.ToString("yyyy-MM-dd HH:mm:ss")
    Return birthday
End Function

Sub save()
    Dim actions = db.Execute("INSERT into table (birthday) VALUE (@birthday)", New table With {.birthday = dapperBugDate(Me.birthday)})
End Sub
0

Converting the DateTime to string worked for me. For example,

using (var conn = new OleDbConnection(connectionString))
{
    conn.Open();
             
    string sql = "Insert into TableName (TableId, DateChanged) values (@TableId, @DateChanged);";
    var effectedRowCount = await conn.ExecuteAsync(sql, new { TableId = 1, DateChanged = DateTime.Now.ToString()});

    conn.Close()
}