F# 查询串联

Lui*_*iso 3 f# type-providers

我使用的SqlDataConnection数据提供者在F#迁移某些行,该迁移的一部分,是为了使这样的3个表之间的连接,把它作为表的继承ABC其中BC继承A这样的事情是我需要得到的是(在类似 Linq 中):

        Bs.Join(As, b.PK, a.FK).Select(new {...})
.Concat(Cs.Join(As, c.PK, a.FK).Select(new {...})
Run Code Online (Sandbox Code Playgroud)

在 中F#,我最接近的是:

 let result = seq {
     yield! query { ... }
     yield! query { ... }
 }
Run Code Online (Sandbox Code Playgroud)

但我被告知这将产生 2 个 SQL 查询,并且总体结果将在内存中。问题是:有没有办法将这种“连接”作为query计算表达式而不使用,seq以便所有这些都发生在单个 SQL 查询中?

Gru*_*oon 5

下面是一些使用 SQLUNIONUNION 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 }
Run Code Online (Sandbox Code Playgroud)

Union扩展方法结合为一体的查询中使用查询UNION

let qUnion = q1.Union(q2)
qUnion.ToList() |> Seq.toList
Run Code Online (Sandbox Code Playgroud)

这是记录的输出:

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]
Run Code Online (Sandbox Code Playgroud)

Concat扩展方法结合为一体的查询中使用查询UNION ALL

let qConcat = q1.Concat(q2)
qConcat.ToList() |> Seq.toList
Run Code Online (Sandbox Code Playgroud)

这是记录的输出:

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]
Run Code Online (Sandbox Code Playgroud)

query表达式中的联合没有特殊语法,AFAIK。