@T-Gro, I'd like to agree on test projects for F# query translation before sending the fixes.
Every query test in the repo runs over AsQueryable(), and LINQ to Objects executes any expression tree, so shapes that break real providers still pass. #11131 and #15648 are closed, but an anonymous record with fields out of alphabetical order still fails in EF Core: the Lambda.Invoke became an Expression.Block with a local variable, which no provider translates either. The same blind spot hides struct tuples (#15522), nested for and double left joins (#8459, #6552) and nested lambdas (#2758).
What I propose:
- Tree-shape tests in
FSharp.Core.UnitTests, with no new dependencies: an IQueryProvider that keeps queries on itself and runs them in memory, plus a validator that fails on nodes a C# expression lambda never contains (blocks, unbound parameters, calls into FSharp.Core, joins nested in a SelectMany collection selector, member reads from a tuple or record built without Members). One line per query shape, about 130 so far. This part is ready.
- A provider test project, e.g.
tests/FSharp.Core.LinqProviders.Tests, that runs the same scenarios on Microsoft.EntityFrameworkCore.Sqlite (in-memory database: real SQL from ToQueryString(), rows compared) and Microsoft.Azure.Cosmos (offline ToQueryDefinition(), no emulator, no network). Only this proves that a shape actually translates.
- Port the ~50 expression-text baselines in
tests/fsharp/core/queriesOverIQueryable to (1); today they run only in the net472 FSharpSuite leg.
Questions:
- Can (2) live in this repo? Restore goes through the dnceng feeds only, so EF Core, SQLitePCLRaw (native
e_sqlite3) and the Cosmos SDK would need to be mirrored into dotnet-public and added to eng/Packages.props. If that is a no-go, I would keep (2) in a separate repo that tests nightly FSharp.Core builds, and land only (1) and (3) here.
- A separate project, or part of
FSharp.Core.UnitTests?
- Which CI legs should run it? It takes under a minute.
@T-Gro, I'd like to agree on test projects for F# query translation before sending the fixes.
Every query test in the repo runs over
AsQueryable(), and LINQ to Objects executes any expression tree, so shapes that break real providers still pass. #11131 and #15648 are closed, but an anonymous record with fields out of alphabetical order still fails in EF Core: theLambda.Invokebecame anExpression.Blockwith a local variable, which no provider translates either. The same blind spot hides struct tuples (#15522), nestedforand double left joins (#8459, #6552) and nested lambdas (#2758).What I propose:
FSharp.Core.UnitTests, with no new dependencies: anIQueryProviderthat keeps queries on itself and runs them in memory, plus a validator that fails on nodes a C# expression lambda never contains (blocks, unbound parameters, calls into FSharp.Core, joins nested in aSelectManycollection selector, member reads from a tuple or record built withoutMembers). One line per query shape, about 130 so far. This part is ready.tests/FSharp.Core.LinqProviders.Tests, that runs the same scenarios onMicrosoft.EntityFrameworkCore.Sqlite(in-memory database: real SQL fromToQueryString(), rows compared) andMicrosoft.Azure.Cosmos(offlineToQueryDefinition(), no emulator, no network). Only this proves that a shape actually translates.tests/fsharp/core/queriesOverIQueryableto (1); today they run only in the net472 FSharpSuite leg.Questions:
e_sqlite3) and the Cosmos SDK would need to be mirrored intodotnet-publicand added toeng/Packages.props. If that is a no-go, I would keep (2) in a separate repo that tests nightly FSharp.Core builds, and land only (1) and (3) here.FSharp.Core.UnitTests?