使用类型填充列表

时间:2016-11-13 21:00:17

标签: f# fsharp.data.sqlclient

我试图用我自己的类型填充列表。

let getUsers =
    use connection = openConnection()
    let getString = "select * from Accounts"
    use sqlCommand = new SqlCommand(getString, connection)
    try
        let usersList = [||]
        use reader = sqlCommand.ExecuteReader()
        while reader.Read() do
            let floresID = reader.GetString 0
            let exName = reader.GetString 1
            let exPass = reader.GetString 2
            let user = [floresID=floresID; exName=exName; exPass=exPass]
            // what here?
            ()
    with
        | :? SqlException as e -> printfn "Došlo k chybě úrovni připojení:\n %s" e.Message
        | _ -> printfn "Neznámá výjimka."

在C#中,我只想将新对象添加到userList中。如何将新user添加到列表中?或者用数据库中的数据获取某种列表是更好的方法吗?

2 个答案:

答案 0 :(得分:2)

最简单的方法是使用类型提供程序,这样您就可以抽象出数据库。您可以将SqlDataConnection用于SQLServer,SqlProvider用于所有内容(包括SQLServer),还可以SQLClient用于SQLServer。

这是一个用于SQLProvider的postgres的dvdrental(示例)数据库的示例:

#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

答案 1 :(得分:1)

使用您的代码,您可以使用列表表达式:

{{1}}

话虽这么说,我会使用FSharp.Data.SqlClient库,所以所有的锅炉板都变成了一行,增加了类型安全的好处(如果更改查询,代码将有编译时错误,这是显而易见的解决。)