前回の例が単一テーブルだったので複数テーブル間の関連があるケースもやってみました。ちょっとはまったのは、F#って前方参照できないのでEmployee <-> Department間の相互参照させることでした。andで繋げてクラス定義すると前方参照もできるようになるみたいです。つまり1ファイルに必ずまとめて定義しろよってことみたいですね。(間違ってたらコメントください)
ということでさくっとコードだけ載せておきます。
namespace SampleApplication
open System
open System.ComponentModel.DataAnnotations
open System.Data.Entity
open System.Data.Objects.DataClasses
open System.Collections.Generic
// クラスは名前空間に所属させる
type Department() =
let mutable id = 0
let mutable name = ""
let mutable employees : ICollection<Employee> = null
member x.ID
with get() = id
and set v = id <- v
member x.Name
with get() = name
and set v = name <- v
abstract Employees : ICollection<Employee> with get, set
default x.Employees
with get() = employees
and set v = employees <- v
// F#は前方参照したいときはandで繋いで定義するらしい・・・
and Employee() =
let mutable id = 0
let mutable name = ""
let mutable department : Department = Department()
member x.ID
with get() = id
and set v = id <- v
member x.Name
with get() = name
and set v = name <- v
abstract Department : Department with get, set
default x.Department
with get() = department
and set v = department <- v
type EduContext() =
inherit DbContext()
// valとDefaultValueを使って未初期化でもOKなように細工
[<DefaultValue>]
val mutable employee : IDbSet<Employee>
[<DefaultValue>]
val mutable department : IDbSet<Department>
member public x.Employees
with get() = x.employee
and set v = x.employee <- v
member public x.Departments
with get() = x.department
and set v = x.department <- v
module Test =
[<EntryPoint>]
let main(_) =
Database.SetInitializer(
DropCreateDatabaseIfModelChanges<EduContext>())
// あとは普通に使える
use ctx = new EduContext()
let dept = Department(Name = "人事部")
ctx.Departments.Add(dept) |> ignore
// 追加
ctx.Employees.Add(Employee(Name = "田中 太郎", Department = dept)) |> ignore
let updateCount = ctx.SaveChanges()
printfn "%d" updateCount
// 再読み込み
ctx.Departments.Load()
// 取得データの表示
ctx.Departments
|> Seq.iter (fun d ->
printfn "%d %s" d.ID d.Name
// 部署にぶらさがってる従業員データも表示
d.Employees |> Seq.iter (fun e -> printfn " %d %s" e.ID e.Name))
0