【问题标题】:F#: Sequence of SQLiteCommand not working, but single SQLiteCommand works. No errors givenF#:SQLiteCommand 序列不起作用,但单个 SQLiteCommand 起作用。没有给出错误
【发布时间】:2019-10-14 14:56:56
【问题描述】:

我正在创建一个通过代码创建 SQLite 数据库的应用程序。

它工作正常,我可以创建一个 Db、表并向表添加属性。

我试图通过一系列查询来优化它,然后一起执行它们。

我注意到 SQLiteCommand 的序列不起作用,但单个 SQLiteCommand 可以正常工作。

这是我的代码与序列一起使用的代码的 sn-p:

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

我真的不明白为什么它不能使用一系列命令,但单个命令有效。 我的意思是,我什至不会返回任何错误,所以我真的不明白问题出在哪里。

可能是连接问题?我需要打开到同一个数据库的多个连接吗?

【问题讨论】:

  • 您应该删除每个ignore。这是一个可以隐藏部分功能应用的枪,例如,这会导致这种情况。
  • @glennsl 我已经删除了忽略,但我仍然遇到同样的问题。此外,为什么我不使用忽略?他们不是要忽略操作的“返回”吗?
  • 如果您将参数添加到使用ignore 调用的函数,那么您最终会忽略部分应用的函数,因此该函数根本不会运行。我已经看到这会导致错误。使用 ignore 时,最好添加类型参数以更明确地说明您忽略的内容,例如ignore<int>,在这种情况下添加参数会导致调用站点出现编译错误。
  • 非常感谢,不知道
  • 啊,忘了你可以在F#中给它一个类型参数。无论如何,您没有使用序列,只是将其丢弃。序列是惰性的,因此除非您以某种方式迭代它,否则它不会做任何事情。这就是这个概念存在的原因。使用Seq.foldSeq.toList 对其进行某事,然后事情就应该开始发生了。

标签: sqlite f# sequence


【解决方案1】:

正如 cmets Seq.map 中提到的那样,它是惰性的,因此不会评估任何序列值。你可以使用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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    相关资源
    最近更新 更多