我曾多次使用FSharp.Data.TypeProvider,但这是我第一次遇到这个bug。我能够连接到SQL数据库没有任何问题,也运行查询,但当我尝试使用任何Seq。函数(例如|> Seq.toArray),我得到一个超时过期错误。
type dbSchema = SqlDataConnection<DBString, Views = false, Functions = false, StoredProcedures = false>
let db = dbSchema.GetDataContext()
返回:
type dbSchema =
class
static member GetDataContext : unit -> edbSchema.ServiceTypes.SimpleDataContextTypes.dbTableOutput
+ 1 overload
nested type ServiceTypes
end
然后我运行一个简单的查询:
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))
返回:
val query1: seq<DateTime * Nullable<int> * float>
现在,如果我尝试运行一些简单的操作,例如:
query1 |> Seq.head
我收到以下错误:
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>.$FSI_0007.main@()
ClientConnectionId:6b4036ff-6ef4-4224-ad7a-08f8b4808b1b
Stopped due to error
我将不胜感激。
由于
我发现了这个:
使用查询表达式时,必须记住查询是 受到懒惰的评价。因此,数据库仍然是开放的 在任何链式评估期间阅读,例如在lambda中 每个查询表达式后的表达式块。任何数据库操作 显式或隐式使用事务必须在之后发生 阅读操作已经完成。
是否有执行查询而不受惰性评估的影响?
我认为可能有一种方法可以使用完整数据上下文和executionquery来实现它,但是你失去了类型提供程序的大部分好处
答案 0 :(得分:0)
除了强制查询到列表外,您还可以在连接字符串中指定超时,例如Connection Timeout = 60
。您可以使用datacontext尝试其他一些操作,例如:
db.DataContext.ObjectTrackingEnabled <- false
db.DataContext.CommandTimeout <- 90
然而,在许多情况下,这些类型的超时问题可以在数据库方面得到更好的解决,你提到你不能这样做。我的大部分超时问题都是通过添加索引来解决的。因此,您可能需要对查询进行性能配置文件。
答案 1 :(得分:0)
我可能会弄错了,但是听起来好像在获取序列的开头时连接已经关闭...
如果要将代码更改为
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)) |> List.ofSeq
会有什么区别吗?也许将序列转换为列表会有所帮助...