我有以下代码从SQL数据库中获取一行。它返回记录或无。但是,它不会返回,因为getLogin的类型为unit = ()
并且存在警告
警告FS0020:此表达式应为“unit”类型,但类型为“login option”。使用'ignore'丢弃表达式的结果,或'let'将结果绑定到名称。
如何解决问题?这是处理Ado.Net的最佳方式吗?
type login = { userName: string; password: string; downloadDir: string}
let getLogin =
let conn = new SqlConnection("Data Source=......;Integrated Security=SSPI;")
try
conn.Open()
let cmd = new SqlCommand("select * FROM Login where website = 'xxx'", conn)
cmd.CommandType <- CommandType.Text
use reader = cmd.ExecuteReader()
if (reader.HasRows) then (
reader.Read() |> ignore
let userName = reader.GetString(5)
let password = reader.GetString(6)
printfn "%s" userName
Some { userName = userName; password = password; downloadDir = "zzz" }
)
else (
printfn "Cannot find login information."
None
)
conn.Close()
with
| :? System.Data.SqlClient.SqlException as sqlEx -> printfn "%A" sqlEx.Message
| _ -> printfn "Unknown Exception"
更新 我已根据Thomas的建议更新了代码。
let getLogin =
use conn = new SqlConnection("Data Source=mdyptcafgprd101;Initial Catalog=App;Integrated Security=SSPI;")
try
conn.Open()
let cmd = new SqlCommand("select * FROM app.WebCrawler.LoginLbl where website = 'CTSLink'", conn)
cmd.CommandType <- CommandType.Text
use reader = cmd.ExecuteReader()
if (reader.HasRows) then (
reader.Read() |> ignore
let userName = reader.GetString(5)
let password = reader.GetString(6)
Some { userName = userName; password = password; downloadDir = "zzz" }
)
else (
printfn "Cannot find login information."
None
)
with
| :? System.Data.SqlClient.SqlException as sqlEx -> printfn "%A" sqlEx.Message
| _ -> printfn "Unknown Exception"
但是,现在它在| :? System...
行上收到以下错误。
s.fs(31,69): error FS0001: Type mismatch. Expecting a 'a -> login option but given a 'a -> unit The type 'login option' does not match the type 'unit' >
答案 0 :(得分:2)
问题是您的if
表达式后跟另一行:
if reader.HasRows then
(...)
else
(...)
conn.Close()
...所以编译器认为你忽略了if
的结果,而是返回最后一个表达式的结果,即conn.Close()
。
解决此问题的最简单方法是使用use
构造 - 当它超出范围时会自动处理conn
值,因此您不需要最后一行并且可以只使用if
作为代码中的最后一个表达式:
use conn = (...)
if reader.HasRows then
(...)
else
(...)
此外,您需要在with ...
分支中返回一些结果 - 处理异常并且您需要引发另一个异常或返回有效值 - 在这种情况下,可能None