如何从匿名函数返回查询并将其传递给转发管道

时间:2014-04-28 19:04:45

标签: f#

我有一个查询,然后转发到匿名函数。我希望此函数利用查询,然后将其转发到下一个函数。不确定这是否可能,因为我无法完成此任务。

到目前为止,我有这个:

// find file for deletion
let findFileToDelete id = 

    // query
    query{
        for row in db.Uploads do
        where (row.Id = id)
        select row
        exactlyOneOrDefault
    } 
    |> (fun q -> File.Delete(q.FilePath)) 

但我想继续这样的事情:

// find file for deletion
let findFileToDelete id = 

    // query
    query{
        for row in db.Uploads do
        where (row.Id = id)
        select row
        exactlyOneOrDefault
    } 
    |> (fun q -> File.Delete(q.FilePath)) q // forward pipe the query
    |> deleteRowFrom db.Uploads q

    // update the database
    saveToDb()

2 个答案:

答案 0 :(得分:4)

正如Mark指出的那样,流水线操作通常用于一系列转换。您的代码执行一系列操作。我建议像这样写:

// find file for deletion
let findFileToDelete id = 

    let row = 
        query {
            for row in db.Uploads do
            where (row.Id = id)
            exactlyOneOrDefault
        } 

    File.Delete row.FilePath
    deleteRowFrom db.Uploads row

    // update the database
    saveToDb()

答案 1 :(得分:2)

F#有很大的空白,分隔多个语句的最正常方法是用换行符分隔它们,所以你应该可以这样做:

let findFileToDelete id = 

    // query
    query{
        for row in db.Uploads do
        where (row.Id = id)
        select row
        exactlyOneOrDefault
    } 
    |> (fun q ->
        File.Delete(q.FilePath)
        q) // forward pipe the query
    |> deleteRowFrom db.Uploads

    // update the database
    saveToDb()

但是,我通常不建议这样做,因为它会在查询中引入副作用。这可能会使您的代码更难以推理。

相反,我建议将查询分配给带有let绑定的值,然后将其传递给Seq.iter以执行带副作用的所有操作,并在查询中重复使用它需要这样做。