Самый простой способ сделать это с помощью поставщика типа, чтобы вы могли абстрагироваться от базы данных. Вы можете использовать SqlDataConnection для SQLServer, SqlProvider для всего (включая SQLServer), а также SQLClient для SQLServer.
Вот пример с dvdrental Postgres (в образце) базы данных для SQLProvider:
#r @"..\packages\SQLProvider.1.0.33\lib\FSharp.Data.SqlProvider.dll"
#r @"..\packages\Npgsql.3.1.8\lib\net451\Npgsql.dll"
open System
open FSharp.Data.Sql
open Npgsql
open NpgsqlTypes
open System.Linq
open System.Xml
open System.IO
open System.Data
let [<Literal>] dbVendor = Common.DatabaseProviderTypes.POSTGRESQL
let [<Literal>] connString1 = @"Server=localhost;Database=dvdrental;User Id=postgres;Password=root"
let [<Literal>] resPath = @"C:\Users\userName\Documents\Visual Studio 2015\Projects\Postgre2\packages\Npgsql.3.1.8\lib\net451"
let [<Literal>] indivAmount = 1000
let [<Literal>] useOptTypes = true
//create the type for the database, based on the connection string, etc. parameters
type sql = SqlDataProvider<dbVendor,connString1,"",resPath,indivAmount,useOptTypes>
//set up the datacontext, ideally you would use `use` here :-)
let ctx = sql.GetDataContext()
let actorTbl = ctx.Public.Actor //alias the table
//set up the type, in this case Records:
type ActorName = {
firstName:string
lastName:string}
//extract the data with a query expression, this gives you type safety and intellisense over SQL (but also see the SqlClient type provider above):
let qry = query {
for row in actorTbl do
select ({firstName=row.FirstName;lastName=row.LastName})
}
//seq is lazy so do all kinds of transformations if necessary then manifest it into a list or array:
qry |> Seq.toArray
две важные части определения записи Actor, а затем в запросе извлечения полей в последовательности Actor записей. Затем вы можете проявить себя в списке или массиве.
Но вы также можете придерживаться своего оригинального решения. В этом случае просто обернуть .Read()
в seq
:
Сначала определяют тип:
type User = {
floresID: string
exName: string
exPass: string
}
Затем извлечь данные:
let recs = cmd.ExecuteReader() // execute the SQL Command
//extract the users into a sequence of records:
let users =
seq {
while recs.Read() do
yield {floresID=recs.[0].ToString()
exName=recs.[1].ToString()
exPass=recs.[2].ToString()
}
} |> Seq.toArray
Если вы уже можете получить нужный вам список из базы данных, это, вероятно, будет лучшим способом. Кроме этого, вы можете использовать 'ResizeArray <_>', который представляет собой .NET. System.Collections.Generic.List <_> '. 'usersList' в настоящее время является массивом, а массивы никогда не могут быть добавлены в .NET. – TeaDrivenDev
Какую базу данных вы используете, и есть ли конкретная причина использовать ADO? Вы должны попытаться получить доступ к нему с помощью поставщика типа. В любом случае вместо массива попробуйте вернуть sqq (IEnumerable) записей. – s952163