diff --git a/All.sln b/All.sln
index 07a3e2b33ea..645fd0c59fd 100644
--- a/All.sln
+++ b/All.sln
@@ -131,6 +131,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.SqlServer.HierarchyI
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.SqlServer.Abstractions", "src\EFCore.SqlServer.Abstractions\EFCore.SqlServer.Abstractions.csproj", "{3D935B7D-80BD-49AD-BDC9-E1B0C9D9494F}"
EndProject
+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "EFCore.VisualBasic.FunctionalTests", "test\EFCore.VisualBasic.FunctionalTests\EFCore.VisualBasic.FunctionalTests.vbproj", "{2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -349,6 +351,10 @@ Global
{3D935B7D-80BD-49AD-BDC9-E1B0C9D9494F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D935B7D-80BD-49AD-BDC9-E1B0C9D9494F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D935B7D-80BD-49AD-BDC9-E1B0C9D9494F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -407,6 +413,7 @@ Global
{8F722A02-71A4-4787-ACD8-FB7D5B7AE648} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
{01F86E65-6448-424C-AAB5-9C6427EF6FD4} = {258D5057-81B9-40EC-A872-D21E27452749}
{3D935B7D-80BD-49AD-BDC9-E1B0C9D9494F} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
+ {2AC6A8AC-5C0A-422A-B21A-CDC8D75F20A3} = {258D5057-81B9-40EC-A872-D21E27452749}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {285A5EB4-BCF4-40EB-B9E1-DF6DBCB5E705}
diff --git a/eng/helix.proj b/eng/helix.proj
index 2f88efebf89..4574f0dceee 100644
--- a/eng/helix.proj
+++ b/eng/helix.proj
@@ -12,7 +12,7 @@
true
true
- $(RepoRoot)/test/EFCore.SqlServer.FunctionalTests/*.csproj;$(RepoRoot)/test/EFCore.SqlServer.HierarchyId.Tests/*.csproj;$(RepoRoot)/test/EFCore.OData.FunctionalTests/*.csproj;$(RepoRoot)/test/EFCore.AspNet.SqlServer.FunctionalTests/*.csproj
+ $(RepoRoot)/test/EFCore.SqlServer.FunctionalTests/*.csproj;$(RepoRoot)/test/EFCore.SqlServer.HierarchyId.Tests/*.csproj;$(RepoRoot)/test/EFCore.OData.FunctionalTests/*.csproj;$(RepoRoot)/test/EFCore.AspNet.SqlServer.FunctionalTests/*.csproj;$(RepoRoot)/test/EFCore.VisualBasic.FunctionalTests/*.vbproj
diff --git a/test/EFCore.VisualBasic.FunctionalTests/EFCore.VisualBasic.FunctionalTests.vbproj b/test/EFCore.VisualBasic.FunctionalTests/EFCore.VisualBasic.FunctionalTests.vbproj
new file mode 100644
index 00000000000..23e12c7bbc7
--- /dev/null
+++ b/test/EFCore.VisualBasic.FunctionalTests/EFCore.VisualBasic.FunctionalTests.vbproj
@@ -0,0 +1,15 @@
+
+
+
+ Microsoft.EntityFrameworkCore
+ net7.0
+ Microsoft.EntityFrameworkCore.VisualBasic.FunctionalTests
+ True
+ latest
+
+
+
+
+
+
+
diff --git a/test/EFCore.VisualBasic.FunctionalTests/NorthwindQueryVisualBasicTest.vb b/test/EFCore.VisualBasic.FunctionalTests/NorthwindQueryVisualBasicTest.vb
new file mode 100644
index 00000000000..0033dfa19b8
--- /dev/null
+++ b/test/EFCore.VisualBasic.FunctionalTests/NorthwindQueryVisualBasicTest.vb
@@ -0,0 +1,96 @@
+' Licensed to the .NET Foundation under one or more agreements.
+' The .NET Foundation licenses this file to you under the MIT license.
+
+Imports Microsoft.EntityFrameworkCore.Query
+Imports Microsoft.EntityFrameworkCore.TestModels.Northwind
+Imports Microsoft.EntityFrameworkCore.TestUtilities
+Imports Xunit
+
+Partial Public Class NorthwindQueryVisualBasicTest
+ Inherits QueryTestBase(Of NorthwindQuerySqlServerFixture(Of NoopModelCustomizer))
+
+ Public Sub New(fixture As NorthwindQuerySqlServerFixture(Of NoopModelCustomizer))
+ MyBase.New(fixture)
+
+ fixture.TestSqlLoggerFactory.Clear()
+ End Sub
+
+
+
+ Public Async Sub CompareString_Equals_Binary(async As Boolean)
+ Await AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Customer).Where(Function(c) c.CustomerID = "ALFKI"),
+ entryCount:=1)
+
+ 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'")
+ End Sub
+
+
+
+ Public Async Sub CompareString_LessThanOrEqual_Binary(async As Boolean)
+ Await AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Customer).Where(Function(c) c.CustomerID <= "ALFKI"),
+ entryCount:=1)
+
+ 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'")
+ End Sub
+
+
+
+ Public Async Sub AddChecked(async As Boolean)
+ Await AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Product).Where(Function(p) p.UnitsInStock + 1 = 102),
+ entryCount:=1)
+
+ AssertSql(
+ "SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[SupplierID], [p].[UnitPrice], [p].[UnitsInStock]
+FROM [Products] AS [p]
+WHERE [p].[UnitsInStock] + CAST(1 AS smallint) = CAST(102 AS smallint)")
+ End Sub
+
+
+
+ Public Async Sub SubtractChecked(async As Boolean)
+ Await AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Product).Where(Function(p) p.UnitsInStock - 1 = 100),
+ entryCount:=1)
+
+ AssertSql(
+ "SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[SupplierID], [p].[UnitPrice], [p].[UnitsInStock]
+FROM [Products] AS [p]
+WHERE [p].[UnitsInStock] - CAST(1 AS smallint) = CAST(100 AS smallint)")
+ End Sub
+
+
+
+ Public Async Sub MultiplyChecked(async As Boolean)
+ Await AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Product).Where(Function(p) p.UnitsInStock * 1 = 101),
+ entryCount:=1)
+
+ AssertSql(
+ "SELECT [p].[ProductID], [p].[Discontinued], [p].[ProductName], [p].[SupplierID], [p].[UnitPrice], [p].[UnitsInStock]
+FROM [Products] AS [p]
+WHERE [p].[UnitsInStock] * CAST(1 AS smallint) = CAST(101 AS smallint)")
+ End Sub
+
+ Protected Overrides Function CreateQueryAsserter(fixture As NorthwindQuerySqlServerFixture(Of NoopModelCustomizer)) As QueryAsserter
+ Return New RelationalQueryAsserter(
+ fixture, AddressOf RewriteExpectedQueryExpression, AddressOf RewriteServerQueryExpression, canExecuteQueryString:=True)
+ End Function
+
+ Private Sub AssertSql(ParamArray expected As String())
+ Fixture.TestSqlLoggerFactory.AssertBaseline(expected)
+ End Sub
+End Class
diff --git a/test/EFCore.VisualBasic.FunctionalTests/NorthwindTextQueryVisualBasicTest.vb b/test/EFCore.VisualBasic.FunctionalTests/NorthwindTextQueryVisualBasicTest.vb
new file mode 100644
index 00000000000..35e36d1f01e
--- /dev/null
+++ b/test/EFCore.VisualBasic.FunctionalTests/NorthwindTextQueryVisualBasicTest.vb
@@ -0,0 +1,29 @@
+' Licensed to the .NET Foundation under one or more agreements.
+' The .NET Foundation licenses this file to you under the MIT license.
+
+Option Compare Text
+Imports Microsoft.EntityFrameworkCore.Diagnostics
+Imports Microsoft.EntityFrameworkCore.TestModels.Northwind
+Imports Xunit
+
+Partial Public Class NorthwindQueryVisualBasicTest
+
+
+ Public Function CompareString_Equals_Text(async As Boolean) As Task
+ Return AssertTranslationFailedWithDetails(
+ Function() AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Customer).Where(Function(c) c.CustomerID = "ALFKI")),
+ CoreStrings.QueryUnableToTranslateMethod("string", "Compare"))
+ End Function
+
+
+
+ Public Function CompareString_LessThanOrEqual_Text(async As Boolean) As Task
+ Return AssertTranslationFailedWithDetails(
+ Function() AssertQuery(
+ async,
+ Function(ss) ss.Set(Of Customer).Where(Function(c) c.CustomerID <= "ALFKI")),
+ CoreStrings.QueryUnableToTranslateMethod("string", "Compare"))
+ End Function
+End Class