我使用的SqlDataConnection数据提供者在F#迁移某些行,该迁移的一部分,是为了使这样的3个表之间的连接,把它作为表的继承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 {...})
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 查询中?
下面是一些使用 SQLUNION或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 }
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。