F#和ADO.NET - 地道的F# [英] F# and ADO.NET - idiomatic F#

查看:242
本文介绍了F#和ADO.NET - 地道的F#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习F#。我写这个F#/ ADO.NET code昨晚。 在哪些方面会提高你的语法 - 让它感觉像地道的F#

I'm just starting to learn F#. I wrote this F#/ADO.NET code last night. In what ways would you improve the syntax - make it feel like idiomatic F#?

    let cn = new OleDbConnection(cnstr)
    let sql = "SELECT * FROM People"
    let da = new OleDbDataAdapter(new OleDbCommand(sql, cn))
    let ds = new DataSet()
    cn.Open()
    let i = da.Fill(ds)
    let rowCol = ds.Tables.[0].Rows
    let rowCount = rowCol.Count
    printfn "%A" rowCount

    for i in 0 .. (rowCount - 1) do
        let row:DataRow = rowCol.[i]
        printfn "%A" row.["LastName"]

注意:的我确实发现了语法检查不喜欢 ROWCOL。[1]。[名字] 什么是正确的方式来处理双索引?我不得不分手的code在两行。

Note: I did find the syntax checker did not like rowCol.[i].["LastName"] What is the proper way to handle dual-indexers? I had to break up the code over two lines.

同时的如果我当时没有下降的数据集路由,使用的加载它的数据到F#​​记录一个SqlDataReader。我应该使用含有该记录集是什么结构? 标准.NET名单,LT;?>

Also If I hadn't gone down the DataSet route and used a SqlDataReader that loaded its data into F# records. What collection structure should I use for containing the records? The standard .NET List<>?

推荐答案

你的code处理.NET API不能正常工作,所以没有办法使这部分$ C $的关键部分Ç特别是更地道或更好。然而,在函数式编程的关键是的抽象的,所以你可以隐藏这个(丑)code到一些地道和可重复使用的功能。

The key part of your code deals with .NET API that is not functional, so there is no way to make this part of the code particularly more idiomatic or nicer. However, the key thing in functional programming is abstraction, so you can hide this (ugly) code into some idiomatic and reusable function.

有关数据的F#重新presenting集合,您可以使用标准的F#列表类型(这是很好的功能数据处理)或者以次&LT;A&GT; (这是标准的.NET 的IEnumerable&LT;A&GT; 的掩护下),与其他.NET库的工作时,它工作得很好

For representing collections of data in F#, you can either use standard F# list type (which is good for functional data processing) or seq<'a> (which is standard .NET IEnumerable<'a> under the cover), which works nicely when working with other .NET libraries.

根据您在其他地方访问数据库中的code,以下可以工作:

Depending on how you access database elsewhere in your code, the following could work:

// Runs the specified query 'sql' and formats rows using function 'f'
let query sql f = 
  // Return a sequence of values formatted using function 'f'
  seq { use cn = new OleDbConnection(cnstr) // will be disposed 
        let da = new OleDbDataAdapter(new OleDbCommand(sql, cn)) 
        let ds = new DataSet() 
        cn.Open() 
        let i = da.Fill(ds) 
        // Iterate over rows and format each row
        let rowCol = ds.Tables.[0].Rows 
        for i in 0 .. (rowCount - 1) do 
            yield f (rowCol.[i]) }

现在您可以使用查询功能大致写你原来的code是这样的:

Now you can use the query function to write your original code roughly like this:

let names = query "SELECT * FROM People" (fun row -> row.["LastName"])
printfn "count = %d" (Seq.count names)
for name in names do printfn "%A" name

// Using 'Seq.iter' makes the code maybe nicer 
// (but that's a personal preference):
names |> Seq.iter (printfn "%A")

您可以写另一个例子是:

Another example you could write is:

// Using records to store the data
type Person { LastName : string; FirstName : string }
let ppl = query "SELECT * FROM People" (fun row -> 
  { FirstName = row.["FirstName"]; LastName = row.["LastName"]; })

let johns = ppl |> Seq.filter (fun p -> p.FirstName = "John")

BTW:通过的的我不会用高阶函数过,如果有一个更直接的方式使用语言结构,例如<$ C $写code关于建议C>为。 ITER 上面这个例子非常简单,有些人会觉得它更具可读性,但没有一般规则......

BTW: Regarding the suggestion by Mau I wouldn't use higher-order functions excessively if there is a more direct way to write the code using language constructs such as for. The example with iter above is simple enough and some people will find it more readable, but there is no general rule...

这篇关于F#和ADO.NET - 地道的F#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆