LINQ to SQL Entity Framework
業務で利用しているので忘れないようにメモします
とにかく、先輩エンジニアの記述したものをまねしながら何となく書いてしまっているので、まだ理解が浅いです。
ので、本当にメモ。
業務で使用した環境:
・SQL Server 2014
・Visual Studio 2015
コードファースト
・用意するもの
-データベース上のテーブルに相当するクラス(=エンティティ(entity: 本質、実体)
-定義したエンティティ クラスを使ってデータベースを生成/テーブル参照するためのクラス(DbContext クラスを継承する)
・主キーは、対象のプロパティの上に[Key]と付ける。
・主キーがint型であるが自動採番したくない場合、
[DatabaseGenerated(DatabaseGeneratedOption.None)]を[Key]の次に付加する。
複数のテーブルの外部結合と内部結合
※クエリはメソッドチェーン(ラムダ式を利用するもの)で業務では記述しました。 ・内部結合・・・Join ・外部結合・・・Groupjoinデータを取得するのに、
JoinではSelect、
GroupJoinではSelectManyを使用。
var query = DB.Table1 //queryはIQueryable型になる
.GroupJoin(DB.Table2.DefaultIfEmpty(), x => x.Column1, T2.Column1, (T1, T2)=> // このxはTable1を指す
new { T2.Column1, T2.Column2, T1.Column3 })
.Join(DB.Table3, (T2, T3)=> new { T3.Column_a, T3.Column_b }).DefaultIfEmpty()
.Where(x => x.Column_a == user_input); // このxは直前のJoinのテーブルが対象となる
...
・DefaultIfEmpty()
もしデータが拾えなかった(データが存在しないもしくは意図していない条件のクエリを書いてしまっているetc.)場合、Emptyで返ってくるところをDefault値(基本null)で返してくれる、というもの。
ポイントとしては、
GroupJoinは結果セットを平坦にして返してくるので(イメージでは result = {{1, 2, 3}, {4, 5, 6}, {...} ...}
のような2次元配列的なものの認識・・・あいまいだが、とにかく内部結合とは結果セットのかたちが違う)、DefaultIfEmpty()はSelectMany()のうしろではなく結合するテーブルのすぐあと、
JoinはSelect()のあとに記述する。
このおかげで、以下のようにクエリ結果を判定できます。
if(query.Any())
{
// クエリでデータが取得できた場合の処理
}
else
{
// データが取得できなかった場合
}
※他にも判断する方法はたくさんあると思いますが、今回はこれを頻繁に使用しました。
データベースファースト
上記の方法は、コードファーストというコードからデータベースを生成する方法でした。 この方法では、Entity Frameworkのしくみで、データベースが存在していなければ自動で生成します。 これはEFの仕様らしいので、それを生成しないようにするのは不可能。 ただ、不具合を起こしてデータベースをデタッチしている際にプログラムがそのデータベースを参照しに行ったとき、 新たにデータベースをつくりそこにデータを登録したり参照してしまうことによってエラーや意図しない動きをしてしまう、場合によっては何か重大な損害が出るとして、 既存のデータベースを参照し、今度はコードを生成してくれる「データベースファースト」なるものを一部に使用しました。 下記サイトさまを参考に実行。案外サクッとできました。 [.NETの各種DBアクセス方法を試す(DataSet,EntityFramework,Dapperなど)](http://endok.hatenablog.com/entry/2018/01/02/142050) いろんな方法を書いてくださってますね。画面キャプチャもコードもあってわかりやすいです。これで、データベースは自動生成されず、コードが自動生成されるので時間も、本当5分くらいしか要さずできました。