So-net無料ブログ作成
検索選択
2017年05月| 2017年06月 |- ブログトップ

Entity Framework - 3 [Programming]

私の場合、Entity Framework に興味があって手を出したわけではなく、単に LINQ to SQL に代わりに使える環境が欲しかったので勉強を始めてみたというだけのものだった。LINQ to SQL が SQL Server に特化したアプローチだったのに対して、Entity Framework が他のデータベースにも対応可能になるということで、乗り換えが促されている感じがする。ただし、現時点では OLE DB や ODBC には対応していないために、コストをかけずに(これが大事) LINQ を体験するには SQL Server を導入する以外に選択肢がない。なので、なんのための Entity Framework なのか今一スッキリしないところもある。既存のデータベースにアクセスしたいならコードファーストなんてアプローチはとりあえず「暇があったら見てみてもいい」程度の進化でしかないしねぇ。

Entity Framework に対応した LINQ to Entities も利用可能ではあるけれど、LINQ to SQL に対し削除されてしまった機能があるのがつらい。今の段階(とりあえず、利用可能な環境を広めたい?)では SQL Server 固有の機能を盛り込むのは難しいのかもしれないけど、完全な互換性を保っていないというのは、かなりの減点対象になると思う。

Sub Main()
    Console.OutputEncoding = System.Text.Encoding.GetEncoding(932)

    Using ex = New 駅データDataContext()
        Dim query =
            From s In ex.Stations
            Where s.Line.line_name Like "*京浜東北線*"
            Order By s.station_cd
            Select New With {s.station_name}
        For Each item In query
            Console.WriteLine(String.Format("{0}", item.station_name))
        Next
    End Using
End Sub

SQL Server (LINQ to SQL) を利用している限りは(DataContext の構築は LINQ to SQL 固有のアプローチですが)普通に利用可能な構文だけど、このまま LINQ to Entities で利用しようとすると、実行時にエラーが発生してしまう。ワイルドカードがの構文が異なるとかいう理由ではなく、Like 演算子が利用できないという理由らしいので、ビルド時にエラーしてくれれば多少は許せるのだけれど、、、。


Entity Framework - 2 [Programming]

プログラムでデータベースを扱うようになると、ほぼ確実にお目にかかるのが Join。

Sub Main()
    Console.OutputEncoding = System.Text.Encoding.GetEncoding(932)

    Console.WriteLine("vb01")
    Using table As New DataTable()
        Using con As New SqlClient.SqlConnection(My.Settings.駅データ)
            Using cmd As New SqlClient.SqlCommand(
                "SELECT s.station_name " &
                "FROM station AS s " &
                "JOIN line AS l ON s.line_cd = l.line_cd " &
                "WHERE l.line_name = @name " &
                "ORDER BY s.station_cd", con
            )
                cmd.Parameters.Add(New SqlClient.SqlParameter("@name", "JR京浜東北線"))
                Using adp As New SqlClient.SqlDataAdapter(cmd)
                    adp.Fill(table)
                End Using
            End Using
        End Using
        For Each item In table.Rows
            Console.WriteLine(String.Format("{0}", item("station_name")))
        Next
    End Using
End Sub

型付けされていない Data Set を使用しているので若干ながくなっているけど、動作は雰囲気で読み取れると思う。これを LINQ を使って書き直すとこうなる。


Sub Main()
    Console.OutputEncoding = System.Text.Encoding.GetEncoding(932)

    Console.WriteLine("vb03")
    Using ex = New 駅データEntities()
        Dim query =
            From s In ex.Stations
            Join l In ex.Lines On s.line_cd Equals l.line_cd
            Where l.line_name = "JR京浜東北線"
            Order By s.station_cd
            Select New With {s.station_name}
        For Each item In query
            Console.WriteLine(String.Format("{0}", item.station_name))
        Next
    End Using
End Sub

これでも一応は動作するのだけれど、もう少し手を入れられる。

Sub Main()
    Console.OutputEncoding = System.Text.Encoding.GetEncoding(932)

    Console.WriteLine("vb03")
    Using ex = New 駅データEntities()
        Dim query =
            From s In ex.Stations
            Where s.Line.line_name = "JR京浜東北線"
            Order By s.station_cd
            Select New With {s.station_name}
        For Each item In query
            Console.WriteLine(String.Format("{0}", item.station_name))
        Next
    End Using
End Sub

LINQ を利用すると Join 句を消し去ることができることがある。代わりに登場するのがコレクションを介して参照先のテーブルアクセスするコード。完全に同じ動作になるわけではないけど、SQL が生理的に馴染まないというプログラマにはお勧めの構文になる。

ソースコードからは読み取れないのだけど、データベースから ADO.NET Entity Data Model を作成することでこのようなカラクリが埋め込まれる。


2017年05月|2017年06月 |- ブログトップ