Ошибка F # linq2SQL или моя ошибка? - PullRequest
0 голосов
/ 21 февраля 2011

Я уже отправил ошибку на fsbugs@microsoft.com , но Я также добавил эту ссылку в письмо для дополнительного описания, выделения кода, обсуждений и , может быть, кто-то найдет способ избежать этого , потому что мне очень нравится и хочу использовать.

Код:

<@ 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: Call (Никто, System.Collections.Generic.IEnumerable * 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, []))]) Это неверный запрос выражение. Проверьте спецификацию разрешенные запросы и рассмотреть возможность перемещения часть запроса из цитаты

Fixed

Код:

    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]) Это недопустимое выражение запроса. Проверьте спецификацию разрешенные запросы и рассмотреть возможность перемещения часть запроса из цитаты

фиксированный

Я не уверен, правильно ли я это делаю, поэтому Я также прошу вас подтвердить, является ли это ошибкой или нет

1 Ответ

2 голосов
/ 21 февраля 2011

В первом случае , Я думаю, что переводчик 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. Я бы попробовал это (...)

EDIT : Это на самом деле некорректное использование 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

Используется объединение цитат . Для получения дополнительной информации об этой функции см. Мою статью (поиск сращивания).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...