问题
I am using SqlDataConnection data provider in F# to migrate some rows, part of that migration is to make a join between 3 tables like this, think of it as an inheritance of tables A, B, C where B and C inherit from A so the thing is I need to get is (in Linq-like):
Bs.Join(As, b.PK, a.FK).Select(new {...})
.Concat(Cs.Join(As, c.PK, a.FK).Select(new {...})
In F#, the closest I got to this was:
let result = seq {
yield! query { ... }
yield! query { ... }
}
but I've been told this will produce 2 SQL queries and the overall result will be on-memory. The question being: is there a way to make this "concatenation" as a query computation expression without using seq so that all happens in a single SQL query?
回答1:
Here's some example code that combines two queries using SQL UNION or UNION ALL.
First, the setup. Note that I've added logging to dbContext so you can see what happens behind the scenes.
#r "System.Data.dll"
#r "System.Data.Linq.dll"
#r "FSharp.Data.TypeProviders.dll"
open System
open System.Linq
open Microsoft.FSharp.Data.TypeProviders
type sql = SqlDataConnection<connStr>
let createDbContext() =
let dbContext = sql.GetDataContext()
// add logging to console
dbContext.DataContext.Log <- System.Console.Out
dbContext
let db = createDbContext()
let products = db.Product
let q1 = query { for x in products do select x }
let q2 = query { for y in products do select y }
The Union extension method combines queries as one query using UNION
let qUnion = q1.Union(q2)
qUnion.ToList() |> Seq.toList
Here's the logged output:
SELECT [t2].[Id], [t2].[Name]
FROM (
SELECT [t0].[Id], [t0].[Name]
FROM [dbo].[Product] AS [t0]
UNION
SELECT [t1].[Id], [t1].[Name]
FROM [dbo].[Product] AS [t1]
) AS [t2]
The Concat extension method combines queries as one query using UNION ALL
let qConcat = q1.Concat(q2)
qConcat.ToList() |> Seq.toList
Here's the logged output:
SELECT [t2].[Id], [t2].[Name]
FROM (
SELECT [t0].[Id], [t0].[Name]
FROM [dbo].[Product] AS [t0]
UNION ALL
SELECT [t1].[Id], [t1].[Name]
FROM [dbo].[Product] AS [t1]
) AS [t2]
There's no special syntax for unions in query expressions, AFAIK.
来源:https://stackoverflow.com/questions/33178027/f-query-concatenation