diff --git a/PetaPoco.Tests.Integration/Databases/MSAccessTests/MSAccessInsertTests.cs b/PetaPoco.Tests.Integration/Databases/MSAccessTests/MSAccessInsertTests.cs
index 37cea6a8..795795e1 100644
--- a/PetaPoco.Tests.Integration/Databases/MSAccessTests/MSAccessInsertTests.cs
+++ b/PetaPoco.Tests.Integration/Databases/MSAccessTests/MSAccessInsertTests.cs
@@ -1,3 +1,6 @@
+using System;
+using PetaPoco.Tests.Integration.Models;
+using Shouldly;
using Xunit;
using PetaPoco.Tests.Integration.Providers;
@@ -11,5 +14,52 @@ public MSAccessInsertTests()
: base(new MSAccessTestProvider())
{
}
+
+ ///
+ /// Regression test for MS Access DateTime millisecond handling.
+ /// MS Access OLE DB provider cannot handle DateTime parameters with sub-second precision.
+ /// Without proper handling in MapParameterValue, DateTime values with milliseconds cause
+ /// "Data type mismatch in criteria expression" errors. The fix truncates milliseconds before
+ /// sending DateTime values to the OLE DB provider.
+ /// See: https://github.com/CollaboratingPlatypus/PetaPoco/issues/736
+ ///
+ [Fact]
+ public void Insert_GivenPocoWithMillisecondPrecisionDateTime_ShouldInsertSuccessfully()
+ {
+ // Test with DateTime that has NO milliseconds (baseline)
+ var personWithoutMillis = new Person
+ {
+ Id = Guid.NewGuid(),
+ Name = "No Milliseconds Person",
+ Age = 35,
+ Height = 180,
+ Dob = new DateTime(2000, 6, 15, 14, 30, 45, 0, DateTimeKind.Utc)
+ };
+
+ _ = DB.Insert(personWithoutMillis);
+ var retrieved1 = DB.Single(personWithoutMillis.Id);
+ retrieved1.ShouldNotBeNull();
+ retrieved1.Dob.ShouldNotBeNull();
+
+ // Test with DateTime that HAS milliseconds (the actual regression test)
+ // Before fix: throws OleDbException "Data type mismatch in criteria expression"
+ // After fix: succeeds but milliseconds are truncated
+ var personWithMillis = new Person
+ {
+ Id = Guid.NewGuid(),
+ Name = "With Milliseconds Person",
+ Age = 40,
+ Height = 185,
+ Dob = new DateTime(2000, 6, 15, 14, 30, 45, 123, DateTimeKind.Utc)
+ };
+
+ _ = DB.Insert(personWithMillis);
+
+ var retrieved2 = DB.Single(personWithMillis.Id);
+ retrieved2.ShouldNotBeNull();
+ retrieved2.Dob.ShouldNotBeNull();
+ // Allow 1 second tolerance because milliseconds are truncated by the fix
+ retrieved2.Dob.Value.ShouldBe(personWithMillis.Dob.Value, TimeSpan.FromSeconds(1));
+ }
}
}
diff --git a/PetaPoco/Providers/MSAccessDatabaseProvider.cs b/PetaPoco/Providers/MSAccessDatabaseProvider.cs
index ea3d47ab..2851361c 100644
--- a/PetaPoco/Providers/MSAccessDatabaseProvider.cs
+++ b/PetaPoco/Providers/MSAccessDatabaseProvider.cs
@@ -48,6 +48,15 @@ public override object MapParameterValue(object value)
return (int)ul;
}
+ // MS Access OLE DB provider cannot handle DateTime parameters with sub-second precision (milliseconds).
+ // Truncate to whole seconds to avoid "Data type mismatch in criteria expression" errors.
+ // See: https://github.com/CollaboratingPlatypus/PetaPoco/issues/736
+ if (value is DateTime dt)
+ {
+ // Remove milliseconds by creating new DateTime with only year/month/day/hour/minute/second
+ return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Kind);
+ }
+
// Let base handle other common conversions (eg: bool -> int)
return base.MapParameterValue(value);
}