欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

F# 优雅使用Dapper进行数据库操作

程序员文章站 2022-06-05 15:33:17
...

本文来自 iteye@fairjm 转截请注明出处

 

之前写过一篇用SQLProvider进行数据库连接的,但实际使用的时候发现兼容性不是很好,在用mysql的时候很多表都找不到,要反复rebuild.

直接使用ADO.NET的话就显得麻烦.
来看一下ADO.NET一个查询到例子

let cStr =@"Server=地址;Port=端口;Database=数据库名称;Uid=用户名;Pwd=密码;"
use conn =newMySqlConnection(cStr)
let command = conn.CreateCommand(
  CommandText="SELECT * FROM user LIMIT 1",
  CommandType=CommandType.Text)
conn.Open()
use reader = command.ExecuteReader()
let idOrder = reader.GetOrdinal("userid")
if reader.Read() then
    // int 可以用string
    printfn "%s"<| reader.GetString(idOrder)
    printfn "%d"<| reader.GetInt32("userid")
    printfn "%s"<| reader.GetString("username")
    printfn "%A"<| reader.GetDateTime("created") 
    // date 也可以用string
    printfn "%s"<| reader.GetString("created")
reader.Close()
conn.Close()

如果要用参数化的话还需要以下代码来设置SqlCommand

//创建SqlCommand对象SqlCommand cmd = conn.CreateCommand();
//默认就是text
cmd.CommandType=CommandType.Text;
//sql语句
cmd.CommandText="select * from products = @ID";  
cmd.Parameters.Add("@ID",SqlDbType.Int);
//给参数sql语句的参数赋值
cmd.Parameters["@ID"].Value=1;

作为常常写脚本的工具,我对数据库查询的需求是使用简单方便,因为是写脚本,所以不会涉及到很多表的JOIN,一对多,多对多的处理等等,能方便读取行数据就可以了.

这一点Dapper可以很好满足.Dapper可以使用dynamic object作为查询参数和返回结果.
但FSharp似乎没有直接使用dynamic object的方式(有的话欢迎打脸...没找着),这里可以借用第三方的项目来.比如FSharp.Interop.Dynamic.
使用之后构建查询就方便多了:

let query =ExpandoObject()
query?userId <-1

也可以直接解析返回结果

需要的扩展:

Install-Package FSharp.Interop.Dynamic
Install-Package MySql.Data -Version 6.9.9
Install-PackageDapper

代码:

open MySql.Data.MySqlClient
open FSharp.Interop.Dynamic
open Dapper
open System
open System.Dynamic

let getConnection (addr, user,pass, db, port)=
    let builder =newMySqlConnectionStringBuilder()
    builder.Server<- addr
    builder.UserID<- user
    builder.Password<-pass
    builder.Database<- db
    builder.Port<- port
    let conn =newMySqlConnection(builder.ConnectionString)
    conn.Open()
    conn

let conn = getConnection("","","","",3306)
let query =ExpandoObject()
query?userId <-1
let obj = conn.QueryFirst("select * from user where userid = @userId", query)
let objs = conn.Query("select * from user limit 10")
printfn "%A" obj?username
objs
|>Seq.iter (fun e -> printfn "%s" e?username)
conn.Close()

对比上面ADO.NET的例子 使用就比较简单直接了~
还有one to many的例子有点长 可以看gist的代码: https://gist.github.com/fairjm/8d2c8b2fd8db549364447a78d2bdad4f

 

本文来自 iteye@fairjm 转截请注明出处