diff --git a/src/EFCore.Jet/EFCore.Jet.csproj b/src/EFCore.Jet/EFCore.Jet.csproj index ee2e6b5..485833e 100644 --- a/src/EFCore.Jet/EFCore.Jet.csproj +++ b/src/EFCore.Jet/EFCore.Jet.csproj @@ -44,6 +44,11 @@ + + + + + diff --git a/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs b/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs index 12de982..7945adc 100644 --- a/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs +++ b/src/EFCore.Jet/Storage/Internal/JetDecimalTypeMapping.cs @@ -1,5 +1,7 @@ using System.Data; using System.Data.Common; +using System.Data.Odbc; +using System.Data.OleDb; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; @@ -77,7 +79,18 @@ 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 + if (parameter is OdbcParameter odbcParameter) + { + odbcParameter.OdbcType = OdbcType.Numeric; + } + else if (parameter is OleDbParameter oleDbParameter) + { + oleDbParameter.OleDbType = OleDbType.Numeric; + } 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)