lycheejam's tech log

チラ裏のメモ帳 | プログラミングは苦手、インフラが得意なつもり。

C# EntityFrameworkのEntityクラスを作成する。

概要

  • 今回作成するEntityクラスのリレーションの説明
  • サンプルプログラムで使用するデータの説明
  • コードの説明

断りになりますが、記事を書いている人は趣味プロの人なのでDB設計等を業務で行ったことがありません。
リレーションがおかしかったり正規化が全然なってないなどあると思います。
また、アノテーションの部分で触れますが初回はカラムの文字数制限等は設定しません。

作成するEntityクラスの全体像

f:id:HM_Atlas:20180507015001p:plain

作成するクラスは以下の5点です。

クラス名 概要
護衛艦クラス 護衛艦の基本情報 ex.所属隊,艦種,艦名,艦船番号etc
護衛隊クラス 護衛艦が所属する隊 ex.第1護衛隊,第2護衛隊
護衛隊群クラス 護衛隊が所属する群 ex.第1護衛隊群,第2護衛隊群
艦種クラス 艦種を識別する艦種記号 ex.DD(汎用護衛艦),DDG(ミサイル護衛艦)
艦級クラス 型を識別する艦級コード ex.ひゅうが型,こんごう型

護衛艦いづれかの護衛隊に所属しており、さらに護衛隊は護衛隊群に所属しています。
また、護衛艦情報の一部として護衛艦クラスから護衛艦の艦種・艦級を特定出来ます。

各艦のデータについてはWikipediaを参照し、海上自衛隊の編成については下記のサイト様を参考にしました。

Entityクラス

目指すべき姿

完成形のコードを示してもちんぷんかんぷんなのでソースのみおいておきます。

Entityクラスの作成

プロジェクト配下にModelsフォルダを新規に作成します。

護衛艦クラス

護衛艦クラスを作成します。

  • プロジェクト/Models/SelfDefenseShip.cs
public class SelfDefenseShip {
    public string EscortDivision { get; set; }  //所属
    public string HullCode { get; set; }  //艦種記号
    public int ShipNumber { get; set; }     //艦識別番号
    public string ShipName { get; set; }    //艦名
    public string ShipClass { get; set; }    //艦種型
    public int StandardDisplacement { get; set; }   //基準排水量(トン)
    public int FullLoadDisplacement { get; set; }   //満載排水量(トン)
    public double FullLength { get; set; }  //全長(メートル)
    public double FullWidth { get; set; }   //全幅(メートル)
    public DateTime CommissionYear { get; set; } //就役(年)
}

メインとなるテーブルと言う言い方もおかしいですが、基本形が出来ました。
さらにここから関連するEntityを作成します。
(正規化と言うべき?ちゃんと正規化はできていないと思うけど)
各Entityとの紐付けは最後にまとめてやります。

護衛隊クラス

護衛艦が所属する護衛隊クラスを作成します。

  • プロジェクト/Models/EscortDivision.cs
public class EscortDivision {
    public int EscortDivisionId { get; set; }   //護衛隊ID
    public string EscortDivisionName { get; set; }  //護衛隊名 ex.第1護衛隊
    public string EscortFlotilla { get; set; }  //所属護衛隊群
    public virtual ICollection<SelfDefenseShip> SelfDefenseShips { get; set; }   //所属艦艇
}

護衛隊には複数の護衛艦が所属しますのでICollection型を使用します。
護衛艦クラスも修正する必要がありますが後でまとめて修正します。

virtualについて

さらに、virtualと言う新しい言葉が出てきました。
クエリを実行する際にLINQ to Entitiesでは遅延実行可能なのですが
virtualを使用してEntity同士を紐付けないと遅延読み込みが出来ません。

詳細については下記のリンクを参照ください。説明出来るほど理解しておりません。

護衛隊群クラス

護衛隊が所属する護衛隊群クラスを作成します。

  • プロジェクト/Models/EscortFlotilla.cs
public class EscortFlotilla {
    public int EscortFlotillaId { get; set; }   //護衛隊群ID
    public string EscortFlotillaName { get; set; }  //護衛隊群名 ex.第1護衛隊群
    public virtual ICollection<EscortDivision> EscortDivision { get; set; }
}

護衛隊群からは所属する護衛隊を認識する必要があるので
virtualを使い関連付けます。また、護衛隊群には複数の護衛隊が所属するのでICollection型を使用します。

さらに護衛隊が所属する護衛隊群を識別する必要があるので護衛隊クラスを修正する必要があります。

  • プロジェクト/Models/EscortDivision.cs
public class EscortDivision {
    public int EscortDivisionId { get; set; }   //護衛隊ID
    public string EscortDivisionName { get; set; }  //護衛隊名 ex.第1護衛隊
    public virtual EscortFlotilla EscortFlotilla { get; set; }  //変更部分
    public virtual ICollection<SelfDefenseShip> SelfDefenseShips { get; set; }   //所属艦艇
}

艦種クラス

護衛艦の種類を特定するための艦種クラスを作成します。

  • プロジェクト/Models/HullCode.cs
public class HullCode {
    public int HullCodeId { get; set; } //艦種記号ID
    public string HullCodeSymbol { get; set; }  //艦種記号 ex.DD,DDG,DDH
    public virtual ICollection<SelfDefenseShip> SelfDefenseShips { get; set; }   //種別護衛艦
}

艦種から護衛艦を認識出来るようにするためにこちらも護衛艦クラスを関連付けます。

艦種について補足

DD、DDH、DDG、DEなどアルファベットの略称で軍艦の種類を識別するコードです。
アメリカ海軍では「船体分類記号」と言っているようです。

艦級クラス

護衛艦の型(クラス)を特定するための艦級クラスを作成します。

  • プロジェクト/Models/ShipClass.cs
public class ShipClass {
    public int ShipClassId { get; set; }    //艦種型ID
    public string ShipClassName { get; set; }   //艦種型名 ex.こんごう型,ひゅうが型
    public virtual ICollection<SelfDefenseShip> SelfDefenseShips { get; set; }   //型別護衛艦
}

こちらも艦種クラスと同様、護衛艦クラスとヒモ付ます。
同型艦が複数存在するのでICollection型を使用します。

護衛艦の○○型について

中長期防衛計画などに基づき計画に沿った防衛力の整備が行われるわけですが
1隻1隻がフルカスタマイズみたいな方法ではなく1隻建造し、それを複数コピーするような感じです。
部品の共通化とかいろいろね?
1隻目に建造された艦の名前が〇〇型の部分に当てはまります。
こんごう型」の場合は4隻いますし、「ひゅうが型」であれば同型艦が2隻います。
こんごう型護衛艦ひゅうが型護衛艦のように呼称します。

護衛艦クラスの修正

Entityクラスが出揃ったので最後に護衛艦クラスを修正します。

  • プロジェクト/Models/SelfDefenseShip.cs
public class SelfDefenseShip {
    public virtual EscortDivision EscortDivision { get; set; }  //修正
    public virtual HullCode HullCode { get; set; }  //修正
    public int ShipNumber { get; set; }     //艦識別番号
    public string ShipName { get; set; }    //艦名
    public virtual ShipClass ShipClass { get; set; }    //修正
    public int StandardDisplacement { get; set; }   //基準排水量(トン)
    public int FullLoadDisplacement { get; set; }   //満載排水量(トン)
    public double FullLength { get; set; }  //全長(メートル)
    public double FullWidth { get; set; }   //全幅(メートル)
    public DateTime CommissionYear { get; set; } //就役(年)
}

所属護衛隊、艦種、艦級を護衛艦クラスから識別出来るようにvirtual+各Entityクラスで紐づけます。

以上で最初に示したソースのクラスと同様になりました。