lycheejam's tech log

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

C# EntityFrameworkのCodeFirstでCRUD(Create)

概要

EntityFrameworkでCRUDのCreateをやってみる。

LINQ to Entitiesの知識が必要になります。
LINQに関しては詳しく解説しないのでご注意ください。

目次

ソース

github.com

今回使用するデータについては全てインサートのサンプルメソッドを作成しておりますので一部しか紹介しません。

後はコード読んでくださいのセルフサービスです。
ちなみにクソコードなのでプルリク待ってます。

DataStoreの作成

今回は命名規約としてDBアクセスを行うクラスを〇〇DataStoreとします。
プロジェクト直下にDataStoreフォルダを作成します。
今回はCreateなのでInsertDataStoreを作成しています。

前提

前回の記事で作成したDbContextを使用してDBに接続しますが、確実にDisposeするためにUsingを使用しています。

using (var db = new ShipsDbContext()) {
    //処理
}

Create基本形

今回は護衛隊群のデータを作成します。
下記のコードは基本形です。
また、CRUD全てに通してですがLINQ to Entitiesを使用します。

  • プロジェクト/DataStore/InsertDataStore.cs
public void InsertFlotillaData() {
    using (var db = new ShipsDbContext()) {
        var ef1 = new EscortFlotilla {
            EscortFlotillaName = "第1護衛隊群"
        };
        db.EscortFlotillas.Add(f1);

        //省略

        var ef5 = new EscortFlotilla {
            EscortFlotillaName = "地域配備部隊"
        };
        db.EscortFlotillas.Add(f5);
        
        db.SaveChanges();
    }
}
  1. DB接続用のShipsDbContextを用意します。
  2. データ追加対象のEntityに対してデータの入った(語弊がある)オブジェクトを用意します。
  3. .Addでデータを追加(この時点ではDBにコミットされていません。)
  4. SaveChangesでDBコミットを行います。

Entityの状態について

.Addの時点でコミットされていないと書いてありますが下記のサイト様を一読すると幸せになれます。

期待する結果

INSERT INTO EscortFlotillas(EscortFlotillaName) VALUES (N'第1護衛隊群');
INSERT INTO EscortFlotillas(EscortFlotillaName) VALUES (N'第2護衛隊群');
INSERT INTO EscortFlotillas(EscortFlotillaName) VALUES (N'第3護衛隊群');
INSERT INTO EscortFlotillas(EscortFlotillaName) VALUES (N'第4護衛隊群');
INSERT INTO EscortFlotillas(EscortFlotillaName) VALUES (N'地方配備部隊');

f:id:HM_Atlas:20180527140758p:plain

実行結果

  • 発行されたSQL
2018/05/27 14:11:37 +09:00 でトランザクションを開始しました

INSERT [dbo].[EscortFlotillas]([EscortFlotillaName]) VALUES (@0)
SELECT [EscortFlotillaId] FROM [dbo].[EscortFlotillas]
WHERE @@ROWCOUNT > 0 AND [EscortFlotillaId] = scope_identity()
-- @0: '第1護衛隊群' (Type = String, Size = -1)

INSERT [dbo].[EscortFlotillas]([EscortFlotillaName]) VALUES (@0)
SELECT [EscortFlotillaId] FROM [dbo].[EscortFlotillas]
WHERE @@ROWCOUNT > 0 AND [EscortFlotillaId] = scope_identity()
-- @0: '第2護衛隊群' (Type = String, Size = -1)

INSERT [dbo].[EscortFlotillas]([EscortFlotillaName]) VALUES (@0)
SELECT [EscortFlotillaId] FROM [dbo].[EscortFlotillas]
WHERE @@ROWCOUNT > 0 AND [EscortFlotillaId] = scope_identity()
-- @0: '第3護衛隊群' (Type = String, Size = -1)

INSERT [dbo].[EscortFlotillas]([EscortFlotillaName]) VALUES (@0)
SELECT [EscortFlotillaId] FROM [dbo].[EscortFlotillas]
WHERE @@ROWCOUNT > 0 AND [EscortFlotillaId] = scope_identity()
-- @0: '第4護衛隊群' (Type = String, Size = -1)

INSERT [dbo].[EscortFlotillas]([EscortFlotillaName]) VALUES (@0)
SELECT [EscortFlotillaId] FROM [dbo].[EscortFlotillas]
WHERE @@ROWCOUNT > 0 AND [EscortFlotillaId] = scope_identity()
-- @0: '地域配備部隊' (Type = String, Size = -1)

2018/05/27 14:11:37 +09:00 でトランザクションをコミットしました

f:id:HM_Atlas:20180527141758p:plain

Create応用形

応用形と言っても方法は無限大(不適切)なのでAddRangeを使ったコードも紹介しておきます。

  • プロジェクト/DataStore/InsertDataStore.cs
public void InsertFlotillaData() {
    using (var db = new ShipsDbContext()) {
        //AddRangeを使った方法
        var ef = new EscortFlotilla[] {
            new EscortFlotilla { EscortFlotillaName = "第1護衛隊群" },
            new EscortFlotilla { EscortFlotillaName = "第2護衛隊群" },
            new EscortFlotilla { EscortFlotillaName = "第3護衛隊群" },
            new EscortFlotilla { EscortFlotillaName = "第4護衛隊群" },
            new EscortFlotilla { EscortFlotillaName = "地域配備部隊" }
        };
        db.EscortFlotillas.AddRange(ef);
        db.SaveChanges();
    }
}

Entityクラスを配列としてAddRangeを使用して配列範囲を一括でDBにInsertしています。

これもまた、オブジェクトブラウザーからデータを確認することが出来ます。
左がデータ追加前、右がデータ追加後です。

f:id:HM_Atlas:20180521214408p:plainf:id:HM_Atlas:20180521214416p:plain

以上

PS:テストデータの追加

テストデータの追加には下記のインサートメソッドのコメントアウトを外して1回のみ実行してください。
特にデータ重複等の制御ははいっていないので実行するたびにデータが追加されます。

//Create
//初回のみ実行すること
var insData = new InsertDataStore();
insData.InsertHullCode();   //艦種コードの追加
insData.InsertShipClass();  //艦型コードの追加
insData.InsertFlotillaData(); //護衛隊群の追加
insData.InsertDivisionData();   //護衛隊コードの追加
insData.InsertShipData();   //艦船データ
//insData.InsertTestShipData();   //テスト用データの追加