F#:SQLiteCommand 序列不工作,但单个 SQLiteCommand 工作。没有给出错误
F#: Sequence of SQLiteCommand not working, but single SQLiteCommand works. No errors given
我正在创建一个通过代码创建 SQLite 数据库的应用程序。
它工作正常,我可以创建数据库、表并向表添加属性。
我试图通过一系列查询来优化它,然后一起执行它们。
我注意到 SQLiteCommand 的序列不起作用,但单个 SQLiteCommand 可以正常工作。
这是我的代码片段,它与序列一起工作:
// Insert attribute
let rec querySeq container = seq {
Console.WriteLine("More attributes? S/N")
match Console.ReadLine() with
| "S" | "s" ->
Console.WriteLine("Name?")
let atrName = Console.ReadLine()
Console.WriteLine("Type?: \n-int\n-string\n-datetime")
let atrType = Console.ReadLine()
match atrType with
| "int" ->
yield sprintf "alter table "+ TableName + " add "+atrName+" integer"
yield! querySeq container
| "string" ->
yield sprintf "alter table "+ TableName + " add "+atrName+" varchar(20)"
yield! querySeq container
| "datetime" ->
yield sprintf "alter table "+ TableName + " add "+atrName+" datetime"
yield! querySeq container
| _ -> failwith "Error in attribute choice"
| "N" | "n" -> sprintf "Done" |> ignore
| _ -> failwith("Only S/N")
}
let container = querySeq Seq.empty
printfn "%A" (Seq.toList container)
//Execute multiple
let commands = Seq.map(fun elem -> new SQLiteCommand(elem, connection) ) container
Seq.map(fun (elem : SQLiteCommand) -> elem.ExecuteNonQuery() ) commands |> ignore
//Try single query
let structureSql = sprintf "alter table "+ TableName + " add t1 varchar(20)"
Console.WriteLine(structureSql)
//Execute query
let structureCommand = new SQLiteCommand(structureSql, connection)
structureCommand.ExecuteNonQuery() |> ignore
connection.Close()
我真的不明白为什么它不能使用一系列命令,但单个命令可以。
我的意思是,我什至不会 return 任何错误,所以我真的不明白问题出在哪里。
会不会是连接问题?我需要打开到同一个数据库的多个连接吗?
如评论中所述,Seq.map
是惰性的,因此正在评估 none 个序列值。您可以使用 Seq.iter
,它会强制对所有项目执行操作:
container
|> Seq.iter(fun elem ->
(new SQLiteCommand(elem, connection)).ExecuteNonQuery() |> ignore<int>)
或for
/do
语法:
for elem in container do
(new SQLiteCommand(elem, connection)).ExecuteNonQuery() |> ignore<int>
我正在创建一个通过代码创建 SQLite 数据库的应用程序。
它工作正常,我可以创建数据库、表并向表添加属性。
我试图通过一系列查询来优化它,然后一起执行它们。
我注意到 SQLiteCommand 的序列不起作用,但单个 SQLiteCommand 可以正常工作。
这是我的代码片段,它与序列一起工作:
// Insert attribute
let rec querySeq container = seq {
Console.WriteLine("More attributes? S/N")
match Console.ReadLine() with
| "S" | "s" ->
Console.WriteLine("Name?")
let atrName = Console.ReadLine()
Console.WriteLine("Type?: \n-int\n-string\n-datetime")
let atrType = Console.ReadLine()
match atrType with
| "int" ->
yield sprintf "alter table "+ TableName + " add "+atrName+" integer"
yield! querySeq container
| "string" ->
yield sprintf "alter table "+ TableName + " add "+atrName+" varchar(20)"
yield! querySeq container
| "datetime" ->
yield sprintf "alter table "+ TableName + " add "+atrName+" datetime"
yield! querySeq container
| _ -> failwith "Error in attribute choice"
| "N" | "n" -> sprintf "Done" |> ignore
| _ -> failwith("Only S/N")
}
let container = querySeq Seq.empty
printfn "%A" (Seq.toList container)
//Execute multiple
let commands = Seq.map(fun elem -> new SQLiteCommand(elem, connection) ) container
Seq.map(fun (elem : SQLiteCommand) -> elem.ExecuteNonQuery() ) commands |> ignore
//Try single query
let structureSql = sprintf "alter table "+ TableName + " add t1 varchar(20)"
Console.WriteLine(structureSql)
//Execute query
let structureCommand = new SQLiteCommand(structureSql, connection)
structureCommand.ExecuteNonQuery() |> ignore
connection.Close()
我真的不明白为什么它不能使用一系列命令,但单个命令可以。 我的意思是,我什至不会 return 任何错误,所以我真的不明白问题出在哪里。
会不会是连接问题?我需要打开到同一个数据库的多个连接吗?
如评论中所述,Seq.map
是惰性的,因此正在评估 none 个序列值。您可以使用 Seq.iter
,它会强制对所有项目执行操作:
container
|> Seq.iter(fun elem ->
(new SQLiteCommand(elem, connection)).ExecuteNonQuery() |> ignore<int>)
或for
/do
语法:
for elem in container do
(new SQLiteCommand(elem, connection)).ExecuteNonQuery() |> ignore<int>