F# で Entity Framework Coreる

この記事はF# Advent Calendar 2017の5日目の記事です。 遅刻しましたごめんなさい…。

F# + .NET Core + Entity Frameworkの組み合わせて開発してみたときの備忘です。 もしかしたら多少古い知識が混ざっているかもれません(全部再検証するには時間がたりなかった)。

モデル定義

CLIMutableにしてEntityFramework側で処理できるようにしておきます。  また、マイグレーション機能を使うためにいくつかAttributeをつけて起きます。

open System
open System.ComponentModel.DataAnnotations
open System.ComponentModel.DataAnnotations.Schema

type UserId = int64

[<CLIMutable>]
type User = {
  [<Key; DatabaseGenerated(DatabaseGeneratedOption.Identity)>]
  Id: UserId
  [<Required; StringLength(32)>]
  Name: string
}

DBContext

だいたいC#のサンプルを翻訳していくだけです。

open Microsoft.EntityFrameworkCore
open Microsoft.Extensions.PlatformAbstractions

type HogeDbContext() =
  inherit DbContext()

  [<DefaultValue>]
  val mutable user : DbSet<User>

  static member val ConnectionString = "" with get, set

  member this.Users
    with get() = this.user
    and set v = this.user <- v

  override __.OnConfiguring(optionsBuilder: DbContextOptionsBuilder) =
    optionsBuilder.UseMySql(SpellbookLibraryDbContext.ConnectionString)
|> ignore

ここではMySQLでの例をだしましたが、他のDBでも大した違いはないはずです。

マイグレーションコード

C#であれば Microsoft.EntityFrameworkCore.Tools.DotNet をインストールしてコマンドを叩いてあげれば C#マイグレーションコードが生成されます。

ではF#であればF#のコードをだして…くれません。

https://github.com/aspnet/EntityFrameworkCore/pull/10289

このpull requestと関連issueを読めばわかりますが、C#以外の言語はコミュニティに任せたそうな雰囲気を感じます。 とはいえ、このpull requestを含む2.1.0はまだリリースされていませんし、コミュニティでツールが作成されるのもそれなりに時間がかかるでしょう。

では、マイグレーションを諦めるのか…といえば、いやいや、方法はあります。

  1. マイグレーション部分だけC#でやる
  2. 生成されたC#コードをすべてF#に書き直す

後者に関しては、F#で書いたモデルクラスからもマイグレーションコードを生成できるので、マイグレーションコードさえなんとかしてしまえば良いわけです。

ただし、2テーブルの作成に200行ほどのF#を書かないといけないので労力に見合っていないのがネックです。

気合で書くか、待つか、ツールを実装するか。 お好みのものをお選び下さい。

F# erがOCamlを触ってみた感想

これは ML Advent Calendar 2017 2日目の記事です。

ここ半年ほど、とある社内勉強会でOCamlを使っているのでその感想をしたためておきます。 さほど中身のない内容ですがご容赦ください…。

  • ビルドツール等は5年くらい前に比べると格段に良くなった気がする
    • opam強い
    • が、jbuilderが便利かどうかはわからない…
  • コンパイル早い
    • F#比
  • エディタどうするべきかは未だ模索中
    • やはりemacsにすべきなのか…?
  • コンパイルエラーのメッセージがわかりにくい気がする?
    • 慣れの問題?
  • functor便利
    • なんでF#にないんや…
  • 第一級モジュール便利
    • F#にもほしい
  • overloadがなくてもなんとかなることを教えてくれる
    • 楽かどうかは別問題
  • F#のノリで書くとだいたいミスする
    • よくinを書き忘れる
    • 括弧(あるいはbegin end)が必要な部分に気付かないことが多い
  • いわゆる函数型言語を触った人ならなんとなくで書けそうな雰囲気
    • 知識の流用がしやすい(当然といえば当然)
    • 私が凝ったことをしていないだけ説はある

あと、プライベートな時間にppxを触ってみましたが使いどころが難しい…。 コンピュテーション式もどきを作ろうとしたのですが、なかなか良い感じにできずお蔵入りしてしまいました。

誰かppxハンズオンしてくだされ~。

新しい言語を触り始めた時に実装してみるもの一覧

ajitofm 13に「言語を学ぶ時に練習で何を実装してみるか」みたいな話が出ていた。 で、自分は何やっているかなーと思ったので書き出してみる。

全部やるってわけではなく、目的に応じていくつかやってみる感じ。

  • parser combinator
    • パフォーマンスを求めないなら数日で実装できる
    • 文字列操作
    • 最適化の練習(文字列編)
  • JSON serializer
    • parser combinatorを使って何かやってみる時の定番?
    • quickcheck的なライブラリを練習するのにちょうど良い
  • binary serializer
    • バイナリ操作
    • マクロ
    • 最適化の練習(バイナリ編)
    • msgpackが仕様の大きさ的にやりやすい?
  • データ構造
    • ひとつひとつは小さいので練習しやすい
    • データ構造、アルゴリズムの復習を兼ねる
  • TODOリスト
    • Webフレームワーク
    • DB
    • logging
  • テスティングフレームワークアサーション
    • リフレクション、メタプログラミング
    • AST変換(power assertもどきを題材に)
    • 同値比較の考察に便利?
    • 完成度は重視しない

他の人がどういうことをやっているのか気になるところ。

技術書典3で F# 入門的なものをだします

なんとかまにあってよかった…。


表示はこんな感じ

f:id:pocketberserker:20171019175103p:plain

高階ことりちゃんの画像は以下のサイトからお借りしました。 CC BY-SA 3.0だそうです。

高階ことり Website

内容としては.NET Core 2.0でF#に入門する的なものになります。 といっても半分くらい文法説明です。

  1. Hello F#
  2. F#の文法
    • ひたすら雑多に文法を説明
  3. 簡単なWeb APIを作ってみる
  4. さらに先へ進むために

500円の予定です。 今のところ電子版の予定はありません。

Utf8Json.FSharpExtensions 0.1.0を試験的にリリース

ある朝、目が覚めたらUtf8Jsonのリリース話とともにメンションが飛んできていました。

ほげぇ、と言いつつ簡単な部分だけ作ったので公開しておきます。

NuGet Gallery | Utf8Json.FSharpExtensions 0.1.0

0.1.0で対応しているのは以下の型です。

  • Option
  • list
  • set
  • map

recordとstruct recordは別に上記ライブラリを使わなくても動きます。

判別共用体は対応するか悩み中です。 そんなに使うのかなぁ、というのが悩んでいる理由です。 でもJSON.NETはサポートしているらしいんですよね…うむむ。

vstestで.NET Coreプロジェクトのコードカバレッジをとる

temporary workaroundらしきものがドキュメントにのっていたのでメモ。

https://github.com/Microsoft/vstest-docs/blob/3c64cbc1a387d6f7f9ebc82a953246322d94cd5c/docs/analyze.md#working-with-code-coverage

こっちのissueが解決されれば、dotnet testコマンドで実行できるようになるようだ?

https://github.com/Microsoft/vstest/issues/981

とはいえ現時点でスケジュールが確定していないので、vstest.console.exeを直接叩くこの方法とは長い付き合いになりそう。

F# で使われるユニットテスティングフレームワークなどの紹介

前にもかいたことがある気がするけれど、2017年度版ということでどうか。 "フレームワーク"と書きつつライブラリも混ぜます。

NUnit

http://nunit.org/

  • よくみかけるやつその1
  • 古の時代から存在するとされている
  • 最近になってウェブサイトがモダンに
  • 地味に進化を続けている
  • .NET Coreに対応している

最近だと

という話を見かけて「へぇ〜」っとなった。 しかしこのAssert.Multipleはどうやって動いているのだろう…?

個人的にもう使う機会はないだろうと思いつつ、なんだかんだ参考になることがあるのでソースは読むだろう。 なんとかUnitに慣れている人ならかける。

xUnit.NET

https://xunit.github.io/

  • よくみかけるやつその2
  • .NET Foundationのもちもの
  • .NET Coreに対応している

コミュニティ的なリソースがあるためか、開発速度がダントツで早い気がする。 .NET界隈(特にC#界隈)のデファクトになる(なっている?)のではないでしょうか。

個人的には、F#製ではないフレームワークの中でならAssertionが好みなのでこれを選ぶ。

MSTest

https://github.com/Microsoft/testfx

  • かつてVisual Studioに標準搭載されていたやつ
  • .NET Coreに対応している

特筆すべきことはない…私が知らないだけかもしれませんが。 新規で使う理由も、特にない…?

FsUnit

https://fsprojects.github.io/FsUnit/

  • NUnitやxUnit.NETといったどちらかといえばC#, VB.NET向けフレームワークAPIをラップしたもの
  • FsUnitTypedというモジュールを使えばAssertionの型チェックを厳密に行える

F# 界隈では一時期みんなこれを使っていたような…今はどうかわからない。 個人的には、shouldみたいなAPIを覚えていられない記憶力になったので使わないと思います。

FsCheck

https://fscheck.github.io/FsCheck/

  • Propery Based TestingとかRamdom Testingとか呼ばれる類のツール
  • 一応単独で実行できる仕組みがある
  • とはいえ、他のテスティングフレームワークと組み合わせる場合がほとんど

Persimmon以外のテスティングフレームワークなら使わない選択肢がない。

expecto

https://github.com/haf/expecto

後述するPersimmonとは違う意味で独特なAPIです。 コンピュテーション式を使い分けることでSync、Async向けテストをかき分けられる。

私にはPersimmonがあるので使わないですが、興味がある方はさわってみると良いかも。

Persimmon

http://persimmon-projects.github.io/Persimmon/

  • F#向けというかF#専用
  • APIが独自路線な関係でいろんなライブラリを再実装している
  • .NET Coreでも一応動く
  • コア開発者が日本人

ライブラリはなぜか色々ある。 名前と機能の関連がわかりにくいという噂あり。

開発者バイアスがかかるので所感は書きません。

unquote

http://www.swensensoftware.com/unquote

  • F#でpower assertしたい的なやつ

他言語のpower assertに比べるとちょっと見劣りする気がしなくもない…?

canopy

http://lefthandedgoat.github.io/canopy/

  • Web UIテスト

F#でかけるよやったね、以上も以下もない気がする。

Foq

https://github.com/fsprojects/Foq

  • テスティングフレームワークと書いてあるが、モックライブラリと認識している人が多い気がする

おわり

数年前に比べて選択肢は増えたが、まだまだ競合が少ない気がする。