まめログ

Javaプログラマの歩み

VB.NETでPostgreSQLに接続する(Entity Framework使用)

VB.NETのプロジェクトから、PostgreSQLへ接続する方法を紹介します。

DBへの接続には、Entity Frameworkを使用します。
今時ODBC接続とかないですよ、本当に。
もっと言っちゃうと、既存システムとかでない限りC#使いましょう。
VB.NETは新規で使う理由が全くありません。

開発環境は以下の通りです。

Entity Frameworkの導入

適当なプロジェクトを作成(ここではWindows Formプロジェクトを作成しています)して、
[参照設定] - [NuGet パッケージの管理]を選択します。

f:id:mamepika:20150401140219j:plain

出てきたウインドウの右上の検索キーワードにEntityと入力すると、
画面の通り、Entity Frameworkが出てくるのでインストールボタンをクリックしてインストールしてください。

f:id:mamepika:20150401140221j:plain

Npgsql for Entity Frameworkの導入

次にPostgreSQLをEntity Frameworkから使用するための、 Npgsql for Entity Frameworkを導入します。
Entity Frameworkと同様に [NuGet パッケージの管理]からNpgsqlを検索して、インストールします。

f:id:mamepika:20150401140223j:plain

設定ファイルへの追記

次に接続文字列などを設定ファイル(App.config)に追記します。

 
  <connectionStrings>
    <add name="WindowsApplication1Context" connectionString="Server=<サーバー名>; Port=<ポート番号> ; User Id=postgres;Password=postgres;Database=postgres" providerName="Npgsql"  />
  </connectionStrings>


  <system.data>
    <DbProviderFactories>
      <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql" type="Npgsql.NpgsqlFactory, Npgsql" />
    </DbProviderFactories>
  </system.data>

エンティティクラスの作成

次にDBのテーブルとマッピングさせるためのエンティティクラスを作成します。
エンティティクラスはいわゆるPOCOエンティティです。

Imports System.ComponentModel.DataAnnotations
Imports System.ComponentModel.DataAnnotations.Schema

<Table("users")>
Public Class User

    <Key>
    <Column("id")>
    Public Property Id As Long

    <Column("name")>
    Public Property Name As String

End Class

クラスのアノテーションでテーブル名と対応付けることが出来、
各プロパティのアノテーションで、主キー属性の指定や、カラム名との対応付けが行えます。

DBコンテキストクラスの作成

次に、DbContextクラスを継承したコンテキストクラスを作成します。

Imports System.Collections.Generic

Imports System.Data.Entity

Public Class WindowsApplication1Context
    Inherits DbContext

    ''' <summary>
    ''' スキーマ名の変更
    ''' </summary>
    ''' <param name="modelBuilder"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
        modelBuilder.HasDefaultSchema("public")
    End Sub

    Public Property Users As DbSet(Of User)

End Class

OnModelCreating()メソッド内で、Entity Frameworkが見に行くスキーマ名を指定できます。
指定しないと「dbo」スキーマを見に行くようです。

クラス名をApp.config内で作成した

<add name="WindowsApplication1Context" ~

のname部分と同じになるようにしてください。

リポジトリクラスの作成

次に登録や削除などの処理を行うリポジトリクラスを作成します。
ここでは「users」テーブルの全件を検索するFindAllメソッドを作成します。

Public Class UserRepository
    Private ReadOnly context As WindowsApplication1Context = New WindowsApplication1Context()

    Public Function FindAll() As List(Of User)
        Return context.Users.ToList()
    End Function

End Class

テーブルの作成

以下のCreate Table文でテーブルを作成します。

create table Users (
  id serial
  , name character varying(30)
  , constraint Users_PKC primary key (id)
) ;

comment on table Users is 'Users';
comment on column Users.id is 'ID';
comment on column Users.name is '名前';

検索出来るように、あらかじめデータも数件入れておきます。

f:id:mamepika:20150401140224j:plain

9期のメンバーの名前だけが入っている簡単なテーブルです。

検索してみる

Form画面にボタンを追
加し、クリックイベントを以下のように定義してみます。

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim userRepo As New UserRepository()

        Dim list = userRepo.FindAll()
        Dim message As New StringBuilder()
        list.ForEach(Sub(l) message.Append(l.Id).Append(vbTab).AppendLine(l.Name))
        MessageBox.Show(message.ToString())
    End Sub

検索出来ました。
f:id:mamepika:20150401140225j:plain

Entity Frameworkを使用すれば、極々シンプルなコードでDBのCRUD処理を記述できます。

SQLを逐一StringBuilderのAppendで作成し、
結果のDataRowをWhile文で一行ずつループさせ、配列やArrayListに詰めるようなコードとはもう金輪際おさらばしましょ