问题
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