教我如何改进我的F#linq2sql seqences
这里我使用linq2sql,但我认为我遇到了问题。
主要问题是ID在这里访问示例我正在制作2嵌入式但我得到了非常可怕的linq2 sql查询因为我不知道是否有一些其他的方法或方法来制作它...
member X.deltaArchive() = // Reacting on delta limits
seq { for a in db.ArchiveAnalogs do
for d in db.Deltas do
if a.ID = d.ID then
if a.Value > d.DeltaLimit then
yield d.AboveMessage
else if a.Value < d.DeltaLimit then
yield d.BelowMessage
} |> Array.ofSeq
所以完整的问题是:有没有办法在不使用嵌入式循环来查找id符合性的情况下做同样的事情?
谢谢。
已添加:
使用:
<@ seq {for a in db.ArchiveAnalogs do
for d in db.Deltas do
if a.ID = d.ID then
if a.Value > d.DeltaLimit then
yield a.Date, d.AboveMessage
else if a.Value < d.DeltaLimit then
yield a.Date, d.BelowMessage}
@> |> query |> Array.ofSeq
收到错误:
The following construct was used in query but is not recognised by the F#-to-LINQ query translator:
Call (None,
System.Collections.Generic.IEnumerable`1[System.Tuple`2[System.DateTime,System.String]] Singleton[Tuple`2](System.Tuple`2[System.DateTime,System.String]),
[NewTuple (PropertyGet (Some (a), System.DateTime Date, []),
PropertyGet (Some (d), System.String AboveMessage, []))])
This is not a valid query expression. Check the specification of permitted queries and consider moving some of the query out of the quotation
offtopic:我必须找到解决方案,因为这是第一个关于“F#linq2sql”的谷歌链接
答案 0 :(得分:2)
首先,您编写的代码段实际上并不是使用LINQ to SQL。您正在内存中运行整个处理,因为F#不会根据类型选择查询运算符(如C#那样)。您需要显式标记查询以在SQL上运行它:
#r "FSharp.PowerPack.Linq.dll"
open Microsoft.FSharp.Linq
<@ seq { for a in db.ArchiveAnalogs do ... } @> |> query
另一种编写所需内容的方法是使用Query.join
函数(来自PowerPack)。我相信以下应该可以解决问题:
<@ join db.ArchiveAnalogs db.Deltas (fun a -> a.ID) (fun d -> d.ID) (fun a d ->
if a.Value > d.DeltaLimit then
yield d.AboveMessage
else if a.Value < d.DeltaLimit then
yield d.BelowMessage ) @> |> query
(虽然,我认为使用join
和嵌套for
之间没有区别 - 如果你在SQL上运行它,那么它可能会优化它以加入它。)