2016-10-17 123 views
2

我知道我需要使用use keywork处置种源:资源管理在F#

use db = new dbml.MobileDataContext(connectionString) 
for rows in db.Item do 
.... 

但我想创建函数返回DB连接:

let getConnection(connectionString) = 
    use db = new dbml.MobileDataContext(connectionString) 
    db.ExecuteCommand(....) |> ignore 
    db 

,并在使用此功能我的代码:

use db = getConnection(connectionString)  
for rows in db.Item do 
.... 

我需要在这种情况下使用use关键字两次:在函数和函数调用中?

+0

从@Tarmil的答案是正确的,但如果你想,你可以在连接上明确调用'.Dispose()'。 – s952163

+1

在这种情况下,'use'必须*不*用于它。 – TeaDrivenDev

回答

6

您应该只在外部函数中使用use。如果你在getConnection里面使用它,那么你的上下文将在从getConnection返回时被处置,所以当你想使用它时,它已经被放置在外部函数中。作为一般规则,如果你在一个函数中处理一个值,那么你不能返回它。

5

@Tarmil有正确的答案,但我也想指出一个更常用的方法来返回一个已经打开的连接。

您可以改为定义一个withConnection高阶函数,它将函数作为其参数。您传入的函数将接受一个打开的连接并返回所需的结果,让withConnection处理连接的处置。这里的样板:

let withConnection f = 
    use db = new dbml.MobileDataContext(connectionString) 
    db.ExecuteCommand(....) |> ignore 
    f db 

然后,您可以使用这样的,而不必担心代码从其他地方关闭连接:

let users = withConnection (fun conn -> conn.ExecuteQuery(...))