2014-12-03 32 views
8

Pracowałem kilka razy z FSharp.Data.TypeProvider, ale po raz pierwszy napotkałem ten błąd. Jestem w stanie połączyć się z bazą danych SQL bez żadnych problemów, a także uruchomić zapytanie, ale kiedy spróbuję użyć dowolnego Seq. (np. |> Seq.toArray), pojawia się błąd przekroczenia limitu czasu.FSharp.Data.TypeProviders SQLDataConnection

type dbSchema = SqlDataConnection<DBString, Views = false, Functions = false, StoredProcedures = false> 
let db = dbSchema.GetDataContext() 

która zwraca:

type dbSchema = 
    class 
    static member GetDataContext : unit -> edbSchema.ServiceTypes.SimpleDataContextTypes.dbTableOutput 
    + 1 overload 
    nested type ServiceTypes 
    end 

następnie uruchomić proste zapytanie:

let query1 = 
    let q = query { for a in db.Products do 
        select (a.Date,a.PId, a.Tax)} 
    q |> Seq.map (fun (a,b,c) -> (a,b,c)) 

która zwraca:

val query1: seq<DateTime * Nullable<int> * float> 

teraz, gdy próbuję uruchomić coś prostego, takich jako:

query1 |> Seq.head 

pojawia się następujący błąd:

System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out 
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
    at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
    at System.Data.SqlClient.SqlDataReader.TryCloseInternal(Boolean closeReader) 
    at System.Data.SqlClient.SqlDataReader.Close() 
    at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReaderSession`1.Dispose() 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.Dispose() 
    at Microsoft.FSharp.Collections.SeqModule.Head[T](IEnumerable`1 source) 
    at <StartupCode$FSI_0007>[email protected]() 
ClientConnectionId:6b4036ff-6ef4-4224-ad7a-08f8b4808b1b 
Stopped due to error 

Będę wdzięczny za każdą pomoc.

Dzięki

Znalazłem to:

When you use a query expression, you must remember that the query is subject to lazy evaluation. Therefore, the database is still open for reading during any chained evaluations, such as in the lambda expression blocks after each query expression. Any database operation that explicitly or implicitly uses a transaction must occur after the read operations have completed.

Czy mimo to wykonanie kwerendy i nie podlega ocenie leniwy?

myślę, że może być jakiś sposób, aby to zrobić za pomocą pełnego kontekstu danych i executionquery jednak niż stracić większość zalet dostawcy typu

+0

Zakładam, że jest to spowodowane tym, że 'seq' jest leniwy, a połączenie z bazą danych nie jest poprawnie skonfigurowane –

+0

Nie jestem odpowiedzialny za bazę danych, jeśli tak jest, czy jest jakiś sposób obejścia tego? Dzięki – user1129988

+0

try: let query1 = let q = query {for a w db.Products do select (a.Date, a.PId, a.Tax)} q |> Seq.map (zabawa (a, b, c) -> (a, b, c)) |> Seq.toList. Dodając seq.toList, zmuszając do uruchomienia kwerendy. – halcwb

Odpowiedz

0

Poza zmuszając zapytanie do listy można określić limit czasu w ciąg połączenia, na przykład Connection Timeout = 60. Istnieje kilka innych rzeczy, które można spróbować z datacontext, na przykład:

db.DataContext.ObjectTrackingEnabled <- false 
db.DataContext.CommandTimeout <- 90 

Jednak w wielu przypadkach ten typ problemów limitu czasu są lepiej rozwiązany po stronie DB, które można wymienić nie można zrobić. Większość problemów z przekroczeniem limitu czasu rozwiązano przez dodanie indeksów. Być może potrzebujesz profilu wydajności w zapytaniu.