Можно ли работать с локальными переменными внутри linq2sql для F #? - PullRequest
1 голос
/ 24 февраля 2011

Пример Linq

<@ seq {for a in db.ArchiveAnalogs do
            for d in db.Deltas do
                let ack = ref false
                for ac in db.Acks do
                    if a.Date > ac.StartDate && a.Date < ac.EndDate then
                        ack := true
                yield
                    if a.ID = d.ID && a.Value > d.DeltaLimit then
                        Some(a.Date, d.AboveMessage, !ack)
                    elif a.ID = d.ID && a.Value < d.DeltaLimit then 
                        Some(a.Date, d.BelowMessage, !ack)
                    else None }
@> |> query |> Seq.choose id |> Array.ofSeq

Сообщение об ошибке:

The following construct was used in query but is not recognised by the F#-to-LINQ query translator:
Sequential (Call (None,
                  Void op_ColonEquals[Boolean](Microsoft.FSharp.Core.FSharpRef`1[System.Boolean], Boolean),
                  [Call (None,
                         Microsoft.FSharp.Core.FSharpRef`1[System.Boolean] Ref[Boolean](Boolean),
                         [Value (false)]), Value (true)]),
            Call (None,
                  System.Collections.Generic.IEnumerable`1[Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[System.DateTime,System.String,System.Boolean]]] Empty[FSharpOption`1](),
                  []))
This is not a valid query expression. Check the specification of permitted queries and consider moving some of the query out of the quotation

Ответы [ 2 ]

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

Нет, невозможно делать то, что ты хочешь. LINQ to SQL позволяет выполнять запросы в виде «деревьев выражений» к базе данных. Оболочка F # преобразует цитаты F # в не зависящие от языка деревья выражений .NET, которые затем передаются в стандартный механизм LINQ to SQL. Есть две проблемы с тем, что вы пытаетесь сделать:

  1. Деревья выражений поддерживают только ограниченный набор операций, а в .NET 3.5 это не включает назначения. Следовательно, даже если цитата F # может содержать назначения локальным переменным, оператор query не может перевести это в дерево выражений .NET.

  2. Даже если назначения могут быть выражены в дереве выражений, как они будут переведены в запрос SQL инфраструктурой LINQ to SQL? Основная идея LINQ to SQL - убедиться, что запрос скомпилирован в SQL и запущен в базе данных, но нет очевидного способа перевести вашу логику в запрос базы данных.

1 голос
/ 25 февраля 2011

Просто, чтобы дать некоторые подробности о сообщении об ошибке - Вы можете использовать let привязку внутри вычислений LINQ to SQL. Проблема в том, что вы используете императивную конструкцию и императивную последовательность выражений.

Ваш запрос содержит что-то вроде этого (где body - это некоторое выражение, которое возвращает unit):

for v in e1 do
  body
yield e3

Это недопустимо, поскольку LINQ to SQL может содержать только деревья выражений C #, которые могут содержать только одно выражение - для его представления нам потребуется поддержка операторов (но это не совсем имеет смысла в базе данных мир).

Чтобы удалить утверждение, переводчик F # преобразует это в нечто (очень грубо), например:

Special.Sequence
  (fun () -> for v in e1 do body) 
  (fun () -> e3)

Теперь это просто одно выражение (метод Sequence живет где-то в библиотеках F #, так что вы можете компилировать цитаты F # с помощью LINQ и запускать их динамически), но транслятор LINQ to SQL не понимает Sequence и не может справиться с этим.

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