2014-12-03 7 views
8

Ho lavorato con il FSharp.Data.TypeProvider un certo numero di volte, ma questa è la prima volta che ho incontrato questo bug. Sono in grado di connettersi al db SQL senza problemi e anche eseguire una query, ma quando provo utilizzare qualsiasi Seq. funzione (come |> Seq.toArray), ottengo un errore scaduto.FSharp.Data.TypeProviders SQLDataConnection

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

che ritorna:

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

poi eseguire una semplice query:

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)) 

che restituisce:

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

ora se si tenta di eseguire qualcosa di semplice come come:

query1 |> Seq.head 

ottengo il seguente errore:

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 

Gradirei qualsiasi aiuto.

Grazie

ho trovato questo:

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.

Esiste un modo per eseguire una query e non è soggetta a valutazione pigra?

penso che ci possa essere un modo per farlo utilizzando contesto dati pieno e executionquery ma di quanto si perde la maggior parte dei benefici del fornitore di tipo

+0

Presumo che ciò avvenga perché 'seq' è pigro e la connessione al database non è stata impostata correttamente –

+0

Non sono responsabile per il database, se questo è il caso, c'è un modo per evitarlo? Grazie – user1129988

+0

provare: lasciare query1 = lasciare q = query {per a in db.Products do select (a.Date, a.PId, a.Tax)} q |> Seq.map (fun (a, b, c) -> (a, b, c)) |> Seq.toList. Quindi aggiungendo un Seq.toList che impone l'esecuzione effettiva della query. – halcwb

risposta

0

Oltre costringendo la query a un elenco, è possibile specificare il timeout in la stringa di connessione, ad esempio Connection Timeout = 60. Ci sono alcune altre cose che potete provare con il DataContext, ad esempio:

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

Tuttavia, in molti casi, questo tipo di problemi di timeout sono meglio risolti sul lato DB, che si parla non si può fare. La maggior parte dei miei problemi di timeout sono stati risolti aggiungendo gli indici. Quindi potrebbe essere necessario per il profilo delle prestazioni la query.