我已经将错误发送到fsbugs@microsoft.com 但我还将此链接添加到信中以获取更多说明,代码突出显示,讨论和也许有人找到某种方法来避免它< / strong>,因为我非常喜欢并希望使用。
代码:
<@ 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
与更新相同的错误消息:
<@ seq {for a in db.ArchiveAnalogs do
for d in db.Deltas do
if a.ID = d.ID && a.Value > d.DeltaLimit then
yield a.Date, d.AboveMessage
elif a.ID = d.ID && 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查询翻译:调用 (没有, System.Collections.Generic.IEnumerable
1[System.Tuple
2 [的System.DateTime,System.String]] 单[元组2](System.Tuple
2 [的System.DateTime,System.String]), [NewTuple(PropertyGet(Some(a),System.DateTime Date,[]), PropertyGet(Some(d),System.String AboveMessage, []))])这不是有效的查询 表达。检查规格 允许查询并考虑移动 一些查询出来的报价
固定
代码:
let px =
query <|
<@ seq { for cl in db.Dictionaries -> cl }
|> Seq.filter(fun x -> x.ID_Line = l1 || x.ID_Line = l2) @>
|> fun pquery ->
query <|
<@ seq { for cd in db.DeltaCompares do
for cl1 in pquery do
if cd.IID1 = cl1.IID then
for cl2 in pquery do
if cd.IID2 = cl2.IID then
yield cl1
yield cl2 } @>
|> List.ofSeq
更新时出现同样的错误:
let p =
[for cl in db.Dictionaries -> cl]
|> Seq.filter(fun x -> x.ID_Line = l1 || x.ID_Line = l2)
|> fun pquery ->
<@ seq { for cd in db.DeltaCompares do
for cl1 in pquery do
for cl2 in pquery do
if cd.IID1 = cl1.IID && cd.IID2 = cl2.IID then
yield cl1, cl2 } @>
|> query |> Seq.collect(fun a -> [fst a; snd a])
错误讯息:
以下构造用于查询但不是 由F#-to-LINQ查询识别 翻译:致电(无, System.Collections.Generic.IEnumerable`1 [LinqBase.Dictionary] SingletonDictionary, [cl1])这不是有效的查询表达式。检查规格 允许查询并考虑移动 一些查询出来的报价
固定
我不确定我是否做得正确所以我还要求您确认这是一个错误还是没有错误
答案 0 :(得分:2)
在第一种情况中,我认为F#-to-LINQ转换器可能在嵌套 if
上失败。你试过了吗(...)
编辑 [第二次尝试] :它也可能失败,因为我们使用if
而没有else
子句。如果您总是使用option
类型返回某些内容然后过滤掉None
值(可能有一种方法可以让它更好,但让我们从这开始),该怎么办:
<@ seq {for a in db.ArchiveAnalogs do
for d in db.Deltas do
yield
if a.ID = d.ID && a.Value > d.DeltaLimit then
Some(a.Date, d.AboveMessage)
elif a.ID = d.ID a.Value < d.DeltaLimit then
Some(a.Date, d.BelowMessage)
else None }
@> |> query |> Seq.choose id |> Array.ofSeq
在第二种情况中,可能会失败,因为 for
嵌套在if
中。我试试这个(...)
编辑:这实际上是错误地使用LINQ(它也不适用于C#)。问题是你正在收集内存中的一些数据(pquery
),然后将其作为输入传递给LINQ(这样它就必须将数据发送回SQL服务器。
您可以尝试这样编写(顺便说一句:我认为使用|> fun x ->
是一个奇怪的构造,只需使用let
就能编写相同的内容):
let pquery = <@ db.Dictionaries
|> Seq.filter(fun x -> x.ID_Line = l1 || x.ID_Line = l2) @>
let px =
<@ seq { for cd in db.DeltaCompares do
for p in %pquery do ... } |> query
这是使用引用拼接。有关此功能的更多信息,请see my article(搜索拼接)。