简体   繁体   English

F#查询连接

[英]F# query concatenation

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): 我使用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 {...})

In F# , the closest I got to this was: F# ,我最接近的是:

 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. 但我被告知这将产生2个SQL查询,整体结果将在内存中。 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? 问题是:是否有一种方法可以将这种“连接”作为query计算表达式而不使用seq以便所有都发生在单个SQL查询中?

Here's some example code that combines two queries using SQL UNION or UNION ALL . 下面是一些使用SQL UNIONUNION ALL组合两个查询的示例代码。

First, the setup. 首先,设置。 Note that I've added logging to dbContext so you can see what happens behind the scenes. 请注意,我已将记录添加到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 }

The Union extension method combines queries as one query using UNION Union扩展方法使用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 Concat扩展方法使用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. query表达式AFAIK中,联合没有特殊的语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM