diff --git a/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs b/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs index 12de982..bc1f84d 100644 --- a/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs +++ b/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs @@ -1,5 +1,6 @@ using System.Data; using System.Data.Common; +using System.Linq; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; @@ -77,7 +78,23 @@ namespace EntityFrameworkCore.Jet.Storage.Internal protected override void ConfigureParameter(DbParameter parameter) { base.ConfigureParameter(parameter); + //Decimals needs to be mapped to Numeric for Jet. + //Using Decimal is fine for OleDb but Odbc doesn't like it. + //Have to use Numeric for Odbc. + //Suspect this will also fix any formatting erros with , and . for decimal separator and space and , for digit separator + //OdbcType.Numeric = 7; + //OleDbType.Numeric = 131; + var setodbctype = parameter.GetType().GetMethods().FirstOrDefault(x => x.Name == "set_OdbcType"); + var setoledbtype = parameter.GetType().GetMethods().FirstOrDefault(x => x.Name == "set_OleDbType"); + if (setodbctype != null) + { + setodbctype.Invoke(parameter, new object?[] { 7 }); + } + else if (setoledbtype != null) + { + setoledbtype.Invoke(parameter, new object?[] { 131 }); + } if (Size.HasValue && Size.Value != -1) { diff --git a/src/EFCore.Jet/Storage/Internal/JetLongTypeMapping.cs b/src/EFCore.Jet/Storage/Internal/JetLongTypeMapping.cs index bbfb6b2..d52b324 100644 --- a/src/EFCore.Jet/Storage/Internal/JetLongTypeMapping.cs +++ b/src/EFCore.Jet/Storage/Internal/JetLongTypeMapping.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +using System.Data.Common; namespace EntityFrameworkCore.Jet.Storage.Internal { @@ -9,7 +10,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal : base(storeType, System.Data.DbType.Int64) { } - + protected JetLongTypeMapping(RelationalTypeMappingParameters parameters) : base(parameters) { @@ -17,5 +18,14 @@ namespace EntityFrameworkCore.Jet.Storage.Internal protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters) => new JetLongTypeMapping(parameters); + + protected override void ConfigureParameter(DbParameter parameter) + { + base.ConfigureParameter(parameter); + //Needs to be Object. Using BigInt doesn't always work + //If the argument value is a long and within Int32 range, having it as BigInt in x86 works + //When running in x64 it fails to convert. Using Object bypasses the conversion + parameter.DbType = System.Data.DbType.Object; + } } } \ No newline at end of file diff --git a/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs index 7b36966..f0f8cb8 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NorthwindWhereQueryJetTest.cs @@ -165,20 +165,20 @@ WHERE `c`.`City` = @__city_0 AssertSql( """ - @__p_0='2' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 - """, +@__p_0='2' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 +""", // """ - @__p_0='5' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 - """); +@__p_0='5' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 +"""); } public override async Task Where_method_call_nullable_type_reverse_closure_via_query_cache(bool isAsync) @@ -187,20 +187,20 @@ WHERE `c`.`City` = @__city_0 AssertSql( """ - @__p_0='1' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE CLNG(`e`.`EmployeeID`) > @__p_0 - """, +@__p_0='1' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE CLNG(`e`.`EmployeeID`) > @__p_0 +""", // """ - @__p_0='5' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE CLNG(`e`.`EmployeeID`) > @__p_0 - """); +@__p_0='5' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE CLNG(`e`.`EmployeeID`) > @__p_0 +"""); } public override async Task Where_method_call_closure_via_query_cache(bool isAsync) @@ -407,26 +407,26 @@ WHERE `c`.`City` = @__InstanceFieldValue_0 AssertSql( """ - @__p_0='2' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 - """, +@__p_0='2' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 +""", // """ - @__p_0='5' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 - """, +@__p_0='5' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 +""", // """ - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE `e`.`ReportsTo` IS NULL - """); +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE `e`.`ReportsTo` IS NULL +"""); } public override async Task Where_simple_closure_via_query_cache_nullable_type_reverse(bool isAsync) @@ -435,26 +435,26 @@ WHERE `c`.`City` = @__InstanceFieldValue_0 AssertSql( """ - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE `e`.`ReportsTo` IS NULL - """, +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE `e`.`ReportsTo` IS NULL +""", // """ - @__p_0='5' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 - """, +@__p_0='5' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 +""", // """ - @__p_0='2' (Nullable = true) - - SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` - FROM `Employees` AS `e` - WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 - """); +@__p_0='2' (Nullable = true) (DbType = Object) + +SELECT `e`.`EmployeeID`, `e`.`City`, `e`.`Country`, `e`.`FirstName`, `e`.`ReportsTo`, `e`.`Title` +FROM `Employees` AS `e` +WHERE IIF(`e`.`ReportsTo` IS NULL, NULL, CLNG(`e`.`ReportsTo`)) = @__p_0 +"""); } public override async Task Where_subquery_closure_via_query_cache(bool isAsync)