Объединение запросов F#
Я использую SqlDataConnection
провайдер данных в F# для переноса некоторых строк, частью этой миграции является объединение трех таблиц, как это, воспринимайте это как наследование таблиц A
, B
, C
где B
а также C
наследовать от A
так что дело в том, что мне нужно получить (в стиле Linq):
Bs.Join(As, b.PK, a.FK).Select(new {...})
.Concat(Cs.Join(As, c.PK, a.FK).Select(new {...})
В F#
ближе всего к этому было:
let result = seq {
yield! query { ... }
yield! query { ... }
}
но мне сказали, что это произведет 2 запроса SQL, и общий результат будет в оперативной памяти. Вопрос заключается в следующем: есть ли способ сделать это "объединение" как query
Вычислительное выражение без использования seq
так что все происходит в одном запросе SQL?
1 ответ
Вот пример кода, который объединяет два запроса с использованием SQL UNION
или же UNION ALL
,
Сначала настройка. Обратите внимание, что я добавил запись в dbContext
так что вы можете видеть, что происходит за кулисами.
#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 }
Union
Метод расширения объединяет запросы как один запрос, используя UNION
let qUnion = q1.Union(q2)
qUnion.ToList() |> Seq.toList
Вот зарегистрированный вывод:
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]
Concat
Метод расширения объединяет запросы как один запрос, используя UNION ALL
let qConcat = q1.Concat(q2)
qConcat.ToList() |> Seq.toList
Вот зарегистрированный вывод:
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]
Там нет специального синтаксиса для союзов в query
выражения, AFAIK.