Ключевая часть вашего кода сделок с .NET API, который не работает, так что нет никакого способа, чтобы сделать эту часть кода особенно более идиоматических или лучше. Однако ключевым в функциональном программировании является абстракция, поэтому вы можете скрыть этот (уродливый) код в какую-то идиоматическую и многоразовую функцию.
Для представления коллекций данных в F # вы можете либо использовать стандартный тип списка F # (который хорош для функциональной обработки данных), либо seq<'a>
(который является стандартным .NET IEnumerable<'a>
под обложкой), который отлично работает при работе с другими .NET.
В зависимости от способа доступа к базе данных в других местах в коде, следующее может работать:
// 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]) }
Теперь вы можете использовать функцию query
, чтобы написать свой исходный код примерно так:
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")
Другим примером можно назвать:
// 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: Что касается предложения Mau Я бы не использовал чрезмерные функции более высокого порядка, если есть более прямой способ написать код с использованием языковых конструкций, таких как for
. Пример с iter
выше достаточно прост, и некоторые люди посчитают его более читаемым, но нет общего правила ...
Не уверен, что я понимаю вопрос. – BuddyJoe
Он имел в виду, что задача под рукой (операции с БД с библиотеками .NET) обязательно заканчивается обязательным кодом, поэтому F # не сияет там. Однако это может быть очень удобно для обработки данных, как только вы получите его из БД. – Mau
@tyndall Mau на 100% прав. ваш код на 100% необходим. вы можете преобразовать его в C# с помощью FindReplace. Я думаю, что F # может быть не лучшим инструментом здесь. – Andrey