TL;DR

内容

リレーショナルデータベースを扱う の一節である。

例: 1 件の Contact を挿入する

Contact を 1 件挿入する writeContact を実装する。型は 選択型をテーブルにマッピングする手法 の Contact を使う。

1. すべてのテーブルの型を定義する

type Db = SqlProgrammabilityProvider<connectionString>

2. writeContact を実装する

ドメインオブジェクトの Contact を受け取り、DB にデータを挿入する。

let writeContact (productionConnection: SqlConnection) (contact: Contact) =
    // ドメインオブジェクトからプリミティブな値を取り出す
    let contactId = contact.ContactId |> ContactId.value
    let isEmail, isPhone, emailAddressOpt, phoneNumberOpt =
        match contact.Info with
        | Email emailAddress ->
            let emailAddressString = emailAddress |> EmailAddress.value
            true, false, Some emailAddressString, None
        | Phone phoneNumber ->
            let phoneNumberString = phoneNumber |> PhoneNumber.value
            false, true, None, Some phoneNumberString
 
    // 新しい行を作る
    let contactInfoTable = new Db.dbo.Tables.ContactInfo()
    let newRow = contactInfoTable.NewRow()
    newRow.ContactId <- contactId
    newRow.IsEmail <- isEmail
    newRow.IsPhone <- isPhone
    newRow.EmailAddress <- emailAddressOpt
    newRow.PhoneNumber <- phoneNumberOpt
 
    // テーブルに追加する
    contactInfoTable.Rows.Add newRow
 
    // DB に変更を反映する
    let recordsAffected = contactInfoTable.Update(productionConnection)
    recordsAffected

3. 別案: SQL 文を実行する

RDB からの読み取り と同じように、SqlCommandProvider で SQL 文を直接実行してもよい。

type InsertContact = SqlCommandProvider<"""
    INSERT INTO ContactInfo
    VALUES (@contactId, @isEmail, @isPhone, @emailAddress, @phoneNumber)
    """, connectionString>
 
let writeContact (productionConnection: SqlConnection) (contact: Contact) =
    let contactId = contact.ContactId |> ContactId.value
    let isEmail, isPhone, emailAddress, phoneNumber =
        match contact.Info with
        | Email emailAddress ->
            let emailAddressString = emailAddress |> EmailAddress.value
            true, false, emailAddressString, null
        | Phone phoneNumber ->
            let phoneNumberString = phoneNumber |> PhoneNumber.value
            false, true, null, phoneNumberString
 
    use cmd = new InsertContact(productionConnection)
    cmd.Execute(contactId, isEmail, isPhone, emailAddress, phoneNumber)

キーワード