なべひろBlog

プログラミングをメインに仕事に関するアレコレを発信しています。

C#でNpgsqlを使ってPostgreSQLへアクセス【接続する】

はじめに
2020年初めにEntityFrameworkを使ったPostgreSQLへアクセスする記事を書きましたが、その後も幾つかEntityFrameworkを用いたアプリを作る中で不満点も出てしまい、昔のようにクエリを直に書いたほうが自分的には分かりやすくクエリのテクニックもC#に限定されず検索できるので楽になったというお話です。
今回は自分のスキルアップ兼ねて同じ事をやるにしても幾つかのパターンがあるのでそれを調べ実際に実行してみて、その後はケースバイケースで使い分けしたいと思っています。
いつもの事ですが余計なプログラムを書くと自分の欲しい情報が余計なプログラムに邪魔され分かりにくくなりますので極力簡潔に書きたいと思います。
また、だらだらと長文になると目的の情報に辿り着くのが大変になりますので機能順に記事にしたいと思います。
Npgsqlの本家情報は
私の作成するサンプルソースファイルは
サンプルソースは記事を書いたタイミングで同じ内容を更新したいと思います。
Npgsqlのインストール
まずやるべき事はNpgsqlのインストールです。
「ツール」-「Nugetパッケージマネージャー」-「ソリューションのNugetパッケージの管理」-「参照」の検索ウインドウで「npgsql」と入力するとおそらく先頭に「Npgsql」が出ると思いますので、それを選択し画面右でプロジェクトを選択しインストールを行います。
Npgsqlをインストール
PostgreSQLへ接続する
今回はPostgreSQLへ接続する手法を微妙に違うものも含め5つのやり方を紹介します。
データベースの構成は
  1. PostgreSQLは自分のPCにインストール(接続先は127.0.0.1)
  2. 接続するポート番号はPostgreSQLでは未使用時のデフォルト5432
  3. ロール(接続時のUser ID)は「test_user」
  4. パスワードは「pass」
  5. 基となるデータベースは「db_PostgreTest」
  6. スキーマはpublic
で検証を行います。
標準的な接続
一番シンプルで特に問題がなければこれでOKな手法です。
using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
con.Open();
いまだにusingやDisposeを省いた解説を時々見受けられますが、とても大事な事なのでこれだけは省略しません。
NpgsqlConnectionはPostgreSQLへ接続するクラスです。
引数なしでも可能ですが、通常は上記のように接続文字列を引数とすれば問題ありません。
複数箇所で接続するプログラムを書くならstring型変数に予め接続文字列を入れておき使い回せば何か変更があった時も修正箇所は1つで済むのでミスは減ります。
接続文字列も簡単に解説すると
  • Server:接続先のIPアドレス(127.0.0.1は自分のPC)
  • Port:接続するポート番号
  • User Id:ログインするロール名
  • Password:ログインするロールのパスワード
  • Database:アクセスするデータベース
  • SearchPath:スキーマの指定(クエリ文で「スキーマ名.テーブル」の「スキーマ名」が省略できる)
接続文字列の「SearchPath」は必ずしも指定する必要はありません。
上記のように指定した場合クエリ文のテーブル名はスキーマ名を省略して””で囲んでください。
NpgsqlConnectionの破棄を非同期にする
await using と記述する事で破棄を非同期で行えます。
非同期にした事で目に見える違いは体験した事はありませんが、時間のかかる処理は効果あるかもしれませんね。
await using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
con.Open();
CancellationTokenなしの非同期接続
非同期接続も存在しています。
非同期接続は引数としてCancellationTokenを用いる方法と以下のようにキャンセル処理を用いない非同期処理が可能です。
接続に時間がかかりUIを固まらせないようにするには非同期接続が有効です。
await using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
await con.OpenAsync();
CancellationTokenありの非同期接続
非同期接続を行いつつ、状況によってはその処理をキャンセルしたい場合の手法です。
CancellationTokenSourceを用いてCancelメソッドを実行する事でそのCancellationTokenを引数として実行されている非同期処理がキャンセルされます。
キャンセル処理が発生すると例外OperationCanceledExceptionが発生しますので、これで判断し以降の処理を行えます。
サンプルではOpenAsyncメソッドを実行する前にCancellationTokenSourceのCancelメソッドを実行し例外OperationCanceledExceptionが発生するかの実験プログラムです。
try
{
    // 例は接続する前にCancelメソッドを実行し例外「OperationCanceledException」に来るかの実験
    tokenSource.Cancel();
    await con.OpenAsync(tokenSource.Token);
}
catch (OperationCanceledException)
{
// 上記処理では必ずこの例外が発生する
}
NpgsqlCommandで接続
あまり使わない手法かもしれませんが、NpgsqlCommandのメソッドで接続も可能です。
using NpgsqlConnection con = new("Server=127.0.0.1; Port=5432; User Id=test_user; Password=pass; Database=db_PostgreTest; SearchPath=public");
using NpgsqlCommand cmd = new NpgsqlCommand();
cmd.Connection = con;
cmd.Connection.Open();
cmd.Connection.Close();
ついでに閉じる動作も可能です。
関連記事