diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs
index 6abb498a288..0964b0368f1 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs
@@ -38,6 +38,7 @@ public SqlServerMethodCallTranslatorProvider(RelationalMethodCallTranslatorProvi
new SqlServerMathTranslator(sqlExpressionFactory),
new SqlServerNewGuidTranslator(sqlExpressionFactory),
new SqlServerObjectToStringTranslator(sqlExpressionFactory),
+ new SqlServerParseTranslator(sqlExpressionFactory),
new SqlServerStringMethodTranslator(sqlExpressionFactory),
new SqlServerTimeOnlyMethodTranslator(sqlExpressionFactory)
});
diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerParseTranslator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerParseTranslator.cs
new file mode 100644
index 00000000000..7f593c88f5c
--- /dev/null
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerParseTranslator.cs
@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
+
+namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
+
+///
+/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+/// the same compatibility standards as public APIs. It may be changed or removed without notice in
+/// any release. You should only use it directly in your code with extreme caution and knowing that
+/// doing so can result in application failures when updating to a new Entity Framework Core release.
+///
+public class SqlServerParseTranslator : IMethodCallTranslator
+{
+ private static readonly Type[] SupportedClrTypes = new Type[]
+ {
+ typeof(bool), // bit
+ typeof(byte), // tinyint
+ typeof(decimal), // decimal(18, 2)
+ typeof(double), // float
+ typeof(float), // float
+ typeof(short), // smallint
+ typeof(int), // int
+ typeof(long) // bigint
+ };
+
+ private static readonly IEnumerable SupportedMethods
+ = SupportedClrTypes
+ .SelectMany(
+ t => t.GetTypeInfo().GetDeclaredMethods(nameof(int.Parse))
+ .Where(
+ m => m.GetParameters().Length == 1
+ && m.GetParameters().First().ParameterType == typeof(string)));
+
+ private readonly ISqlExpressionFactory _sqlExpressionFactory;
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public SqlServerParseTranslator(ISqlExpressionFactory sqlExpressionFactory)
+ {
+ _sqlExpressionFactory = sqlExpressionFactory;
+ }
+
+ ///
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
+ ///
+ public virtual SqlExpression? Translate(
+ SqlExpression? instance,
+ MethodInfo method,
+ IReadOnlyList arguments,
+ IDiagnosticsLogger logger)
+ => SupportedMethods.Contains(method)
+ ? _sqlExpressionFactory.Convert(
+ arguments[0],
+ method.ReturnType)
+ : null;
+}
diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs
index 17c7cc3b7c6..26832bce839 100644
--- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs
@@ -901,6 +901,158 @@ public override async Task Convert_ToString(bool async)
AssertSql();
}
+ public override async Task Byte_Parse(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Byte_Parse(async));
+
+ AssertSql();
+ }
+
+ public override async Task Byte_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Byte_Parse_Non_Numeric_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Byte_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Byte_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ AssertSql();
+ }
+
+ public override async Task Byte_Parse_Negative_Overflows(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Byte_Parse_Negative_Overflows(async));
+
+ AssertSql();
+ }
+
+ public override async Task Byte_Parse_Decimal_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Byte_Parse_Decimal_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Decimal_Parse(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Decimal_Parse(async));
+
+ AssertSql();
+ }
+
+ public override async Task Decimal_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Decimal_Parse_Non_Numeric_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Double_Parse(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Double_Parse(async));
+
+ AssertSql();
+ }
+
+ public override async Task Double_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Double_Parse_Non_Numeric_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Short_Parse(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Short_Parse(async));
+
+ AssertSql();
+ }
+
+ public override async Task Short_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Short_Parse_Non_Numeric_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Short_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Short_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ AssertSql();
+ }
+
+ public override async Task Short_Parse_Decimal_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Short_Parse_Decimal_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Int_Parse(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Int_Parse(async));
+
+ AssertSql();
+ }
+
+ public override async Task Int_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Int_Parse_Non_Numeric_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Int_Parse_Decimal_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Int_Parse_Decimal_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Long_Parse(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Long_Parse(async));
+
+ AssertSql();
+ }
+
+ public override async Task Long_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Long_Parse_Non_Numeric_Bad_Format(async));
+
+ AssertSql();
+ }
+
+ public override async Task Long_Parse_Decimal_Bad_Format(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(() => base.Long_Parse_Decimal_Bad_Format(async));
+
+ AssertSql();
+ }
+
public override async Task Indexof_with_emptystring(bool async)
{
await base.Indexof_with_emptystring(async);
diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindFunctionsQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindFunctionsQueryInMemoryTest.cs
index 0963a03494e..c80a025a1ff 100644
--- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindFunctionsQueryInMemoryTest.cs
+++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindFunctionsQueryInMemoryTest.cs
@@ -14,4 +14,56 @@ public class NorthwindFunctionsQueryInMemoryTest : NorthwindFunctionsQueryTestBa
{
//TestLoggerFactory.TestOutputHelper = testOutputHelper;
}
+
+ public override Task Byte_Parse_Non_Numeric_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Byte_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Byte_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Byte_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ public override Task Byte_Parse_Negative_Overflows(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Byte_Parse_Negative_Overflows(async));
+
+ public override Task Byte_Parse_Decimal_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Byte_Parse_Decimal_Bad_Format(async));
+
+ public override Task Decimal_Parse_Non_Numeric_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Decimal_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Double_Parse_Non_Numeric_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Double_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Short_Parse_Non_Numeric_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Short_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Short_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Short_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ public override Task Short_Parse_Decimal_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Short_Parse_Decimal_Bad_Format(async));
+
+ public override Task Int_Parse_Non_Numeric_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Int_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Int_Parse_Decimal_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Int_Parse_Decimal_Bad_Format(async));
+
+ public override Task Long_Parse_Non_Numeric_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Long_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Long_Parse_Decimal_Bad_Format(bool async)
+ => Assert.ThrowsAsync(
+ () => base.Long_Parse_Decimal_Bad_Format(async));
}
diff --git a/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs
index 879031ceef8..cce61fd3d0c 100644
--- a/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs
+++ b/test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs
@@ -1556,6 +1556,229 @@ public virtual async Task Convert_ToString(bool async)
}
}
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Byte_Parse(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ byte.Parse(c.Phone.Substring(0, 3)) == 30),
+ entryCount: 1);
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Byte_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ byte.Parse(c.CustomerID) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Byte_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ byte.Parse(c.PostalCode) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Byte_Parse_Negative_Overflows(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ byte.Parse(c.Phone.Substring(3, 4)) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Byte_Parse_Decimal_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "BLONP" &&
+ byte.Parse(c.Phone.Substring(0, 4)) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual async Task Decimal_Parse(bool async)
+ {
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ decimal.Parse(c.PostalCode) == 12209m),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "BLONP" &&
+ decimal.Parse(c.Phone.Substring(0, 4)) == 88.6m),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ decimal.Parse(c.Phone.Substring(3, 4)) == -7m),
+ entryCount: 1);
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Decimal_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ decimal.Parse(c.CustomerID) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual async Task Double_Parse(bool async)
+ {
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ double.Parse(c.PostalCode) == 12209d),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "BLONP" &&
+ double.Parse(c.Phone.Substring(0, 4)) == 88.6d),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ double.Parse(c.Phone.Substring(3, 4)) == -7d),
+ entryCount: 1);
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Double_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ double.Parse(c.CustomerID) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual async Task Short_Parse(bool async)
+ {
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ short.Parse(c.PostalCode) == 12209),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ short.Parse(c.Phone.Substring(3, 4)) == -7),
+ entryCount: 1);
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Short_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ short.Parse(c.CustomerID) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Short_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "BLAUS" &&
+ short.Parse(c.PostalCode) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Short_Parse_Decimal_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "BLONP" &&
+ short.Parse(c.Phone.Substring(0, 4)) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual async Task Int_Parse(bool async)
+ {
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ int.Parse(c.PostalCode) == 12209),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ int.Parse(c.Phone.Substring(3, 4)) == -7),
+ entryCount: 1);
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Int_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ int.Parse(c.CustomerID) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Int_Parse_Decimal_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "BLONP" &&
+ int.Parse(c.Phone.Substring(0, 4)) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual async Task Long_Parse(bool async)
+ {
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ long.Parse(c.PostalCode) == 12209L),
+ entryCount: 1);
+
+ await AssertQuery(
+ async,
+ ss => ss.Set().Where(c => c.CustomerID == "ALFKI" &&
+ long.Parse(c.Phone.Substring(3, 4)) == -7L),
+ entryCount: 1);
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Long_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "ALFKI" &&
+ long.Parse(c.CustomerID) == 0));
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Long_Parse_Decimal_Bad_Format(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set()
+ .Where(c => c.CustomerID == "BLONP" &&
+ long.Parse(c.Phone.Substring(0, 4)) == 0));
+
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Indexof_with_emptystring(bool async)
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs
index d8aa23243aa..d3a714ae69e 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore.TestModels.Northwind;
namespace Microsoft.EntityFrameworkCore.Query;
@@ -2129,6 +2130,198 @@ public override async Task Convert_ToString(bool async)
""");
}
+ public override async Task Byte_Parse(bool async)
+ {
+ await base.Byte_Parse(async);
+
+ AssertSql(
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST(SUBSTRING([c].[Phone], 0 + 1, 3) AS tinyint) = CAST(30 AS tinyint)");
+ }
+
+ public override async Task Byte_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Byte_Parse_Non_Numeric_Bad_Format(async));
+
+ Assert.Equal(245, exception.Number); //245 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Byte_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Byte_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ Assert.Equal(244, exception.Number); //244 is a database engine error for failed conversion because of overflow
+ }
+
+ public override async Task Byte_Parse_Negative_Overflows(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Byte_Parse_Negative_Overflows(async));
+
+ Assert.Equal(244, exception.Number); //244 is a database engine error for failed conversion because of overflow
+ }
+
+ public override async Task Byte_Parse_Decimal_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Byte_Parse_Decimal_Bad_Format(async));
+
+ Assert.Equal(245, exception.Number); //245 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Decimal_Parse(bool async)
+ {
+ await base.Decimal_Parse(async);
+
+ AssertSql(
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST([c].[PostalCode] AS decimal(18,2)) = 12209.0",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'BLONP' AND CAST(SUBSTRING([c].[Phone], 0 + 1, 4) AS decimal(18,2)) = 88.6",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST(SUBSTRING([c].[Phone], 3 + 1, 4) AS decimal(18,2)) = -7.0");
+ }
+
+ public override async Task Decimal_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Decimal_Parse_Non_Numeric_Bad_Format(async));
+
+ Assert.Equal(8114, exception.Number); //8114 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Double_Parse(bool async)
+ {
+ await base.Double_Parse(async);
+
+ AssertSql(
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST([c].[PostalCode] AS float) = 12209.0E0",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'BLONP' AND CAST(SUBSTRING([c].[Phone], 0 + 1, 4) AS float) = 88.599999999999994E0",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST(SUBSTRING([c].[Phone], 3 + 1, 4) AS float) = -7.0E0");
+ }
+
+ public override async Task Double_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Double_Parse_Non_Numeric_Bad_Format(async));
+
+ Assert.Equal(8114, exception.Number); //8114 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Short_Parse(bool async)
+ {
+ await base.Short_Parse(async);
+
+ AssertSql(
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST([c].[PostalCode] AS smallint) = CAST(12209 AS smallint)",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST(SUBSTRING([c].[Phone], 3 + 1, 4) AS smallint) = CAST(-7 AS smallint)");
+ }
+
+ public override async Task Short_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Short_Parse_Non_Numeric_Bad_Format(async));
+
+ Assert.Equal(245, exception.Number); //245 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Short_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Short_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ Assert.Equal(244, exception.Number); //244 is a database engine error for failed conversion because of overflow
+ }
+
+ public override async Task Short_Parse_Decimal_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Short_Parse_Decimal_Bad_Format(async));
+
+ Assert.Equal(245, exception.Number); //245 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Int_Parse(bool async)
+ {
+ await base.Int_Parse(async);
+
+ AssertSql(
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST([c].[PostalCode] AS int) = 12209",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST(SUBSTRING([c].[Phone], 3 + 1, 4) AS int) = -7");
+ }
+
+ public override async Task Int_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Int_Parse_Non_Numeric_Bad_Format(async));
+
+ Assert.Equal(245, exception.Number); //245 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Int_Parse_Decimal_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Int_Parse_Decimal_Bad_Format(async));
+
+ Assert.Equal(245, exception.Number); //245 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Long_Parse(bool async)
+ {
+ await base.Long_Parse(async);
+
+ AssertSql(
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST([c].[PostalCode] AS bigint) = CAST(12209 AS bigint)",
+ //
+ @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
+FROM [Customers] AS [c]
+WHERE [c].[CustomerID] = N'ALFKI' AND CAST(SUBSTRING([c].[Phone], 3 + 1, 4) AS bigint) = CAST(-7 AS bigint)");
+ }
+
+ public override async Task Long_Parse_Non_Numeric_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Long_Parse_Non_Numeric_Bad_Format(async));
+
+ Assert.Equal(8114, exception.Number); //8114 is a database engine error for failed conversion because of unsuitable data type
+ }
+
+ public override async Task Long_Parse_Decimal_Bad_Format(bool async)
+ {
+ var exception = await Assert.ThrowsAsync(
+ () => base.Long_Parse_Decimal_Bad_Format(async));
+
+ Assert.Equal(8114, exception.Number); //8114 is a database engine error for failed conversion because of unsuitable data type
+ }
+
public override async Task Indexof_with_emptystring(bool async)
{
await base.Indexof_with_emptystring(async);
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs
index 75b71e662be..39710184afb 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs
@@ -42,6 +42,63 @@ public override Task Convert_ToInt64(bool async)
public override Task Convert_ToString(bool async)
=> AssertTranslationFailed(() => base.Convert_ToString(async));
+ public override Task Byte_Parse(bool async)
+ => AssertTranslationFailed(() => base.Byte_Parse(async));
+
+ public override Task Byte_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Byte_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Byte_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ => AssertTranslationFailed(() => base.Byte_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ public override Task Byte_Parse_Negative_Overflows(bool async)
+ => AssertTranslationFailed(() => base.Byte_Parse_Negative_Overflows(async));
+
+ public override Task Byte_Parse_Decimal_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Byte_Parse_Decimal_Bad_Format(async));
+
+ public override Task Decimal_Parse(bool async)
+ => AssertTranslationFailed(() => base.Decimal_Parse(async));
+
+ public override Task Decimal_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Decimal_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Double_Parse(bool async)
+ => AssertTranslationFailed(() => base.Double_Parse(async));
+
+ public override Task Double_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Double_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Short_Parse(bool async)
+ => AssertTranslationFailed(() => base.Short_Parse(async));
+
+ public override Task Short_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Short_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Short_Parse_Greater_Than_Max_Value_Overflows(bool async)
+ => AssertTranslationFailed(() => base.Short_Parse_Greater_Than_Max_Value_Overflows(async));
+
+ public override Task Short_Parse_Decimal_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Short_Parse_Decimal_Bad_Format(async));
+
+ public override Task Int_Parse(bool async)
+ => AssertTranslationFailed(() => base.Int_Parse(async));
+
+ public override Task Int_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Int_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Int_Parse_Decimal_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Int_Parse_Decimal_Bad_Format(async));
+
+ public override Task Long_Parse(bool async)
+ => AssertTranslationFailed(() => base.Long_Parse(async));
+
+ public override Task Long_Parse_Non_Numeric_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Long_Parse_Non_Numeric_Bad_Format(async));
+
+ public override Task Long_Parse_Decimal_Bad_Format(bool async)
+ => AssertTranslationFailed(() => base.Long_Parse_Decimal_Bad_Format(async));
+
public override Task Projecting_Math_Truncate_and_ordering_by_it_twice(bool async)
=> AssertTranslationFailed(() => base.Projecting_Math_Truncate_and_ordering_by_it_twice(async));