WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

PostgreSQL とデータソース構成ウィザード

by WebSurfer 5. October 2022 16:14

PostgreSQL の既存のデータベースから Visual Studio 2022 のデータソース構成ウィザードを利用して型付 DataSet / DataTable + TableAdapter を作ることができます。それを使って、DB のレコードの一覧表示・編集ができる Windows Forms + GataGridView アプリを容易に作成できます。

Windows Forms + GataGridView アプリ

SQL Server の場合は当たり前の話なので何をいまさらと言われるかもしれませんが、先日初めて PostgreSQL をインストールしたので試してみた次第です。

(ASP.NET MVC5 アプリで Entity Framework 6 を使って PostgreSQL の既存の DB の CRUD を行う場合については、先の記事「PostgreSQL で EF6 DB First」に書きましたので、興味があれば見てください)

この記事を書いた時の環境は以下の通りです。

  • PostgreSQL 14.4
  • Visual Studio Community 2022 17.3.5
  • Npgsql PostgreSQL Integration 4.1.12
  • Npgsql 6.0.7
  • .NET Framework 4.8
  • Windows フォームアプリケーション (.NET Framework)

Visual Studio で PostgreSQL に対してデータソース構成ウィザードが使えるようにするには Npgsql PostgreSQL Integration という拡張機能の追加が必要です。下の画像のバージョン 4.1.12 は Visual Studio 2022 用にリリースされたものだそうです。

Npgsql PostgreSQL Integration

拡張機能の追加後、Microsoft のドキュメント「新しいデータ ソースの追加」のようにデータソース構成ウィザードを起動すれば、「データ接続の選択」で PostgreSQL Database を選択できるようになります。

データ接続の選択

以下のように PostgreSQL への接続情報を設定して接続できれば、

接続情報を設定

そのあとは SQL Server とほぼ同様な手順で DataSet(xsd ファイル)を作成できます。

DataSet(xsd ファイル)

xsd ファイルが作成できると、デザイン画面でデータソースウィンドウに DataSet / DataTable が表示されるので (下の画像で MovieDataSet / Movie)、DataTable (Movie) の DataGridView を選択してから Form にドラッグ&ドロップします。

データソースウィンドウの DataSet / DataTable

上の画像はドラッグ&ドロップして必要なコードがすべて生成された後、DataGridView.Dock プロパティを Fill に設定したものです。

次に NuGet から Npgsql をインストールします。

NuGet から Npgsql をインストール

その後ソリューションをビルドして実行すればこの記事の一番上の画像のようなアプリが動きます。DataGridView を編集した結果も期待通り DB に反映されます。

ただ、微妙なところがあって、なぜか Npgsql のインストールのタイミングが問題で、自分の環境で試した時は以下の順番で行う必要がありましたので注意してください。

  1. データソース構成ウィザードを起動し型付 DataSet / DataTable + TableAdapter を生成
  2. 「データソース」ウィンドウから作成した DataTable を Form にドラッグ&ドロップ
  3. NuGet から Npgsql をインストール
  4. ソリューションをビルド

想像ですが、データソース構成ウィザードが使う Npgsql と NuGet からインストールする Npgsql やその他の関係 dll とのバージョンの不整合が問題ではないかと思われます。

Tags: , ,

.NET Framework

ユーザー対話モード

by WebSurfer 18. September 2022 13:58

IIS でホストされる ASP.NET Web アプリはユーザー対話モードでは動かないという話を書きます。

Environment.UserInteractive

ASP.NET Web アプリを、開発環境で Visual Studio から実行して IIS Express 上で動かすと期待通り動くが、運用環境で IIS にデプロイすると動かないという話を耳にします。

その原因のほどんどは、(1) ワーカープロセスのアクセス権の違い、(2) プロセスがユーザー対話モードで動いているか否かです。(加えて、Session 0 分離による制約もあります。詳しくは、Microsoft の文書 Impact of Session 0 Isolation on Services and Drivers in Windows を見てください)

開発環境の時は、PC にログインしたアカウントで Visual Studio を起動しているので、(1) は PC にログインしたユーザーアカウントの権限、(2) はユーザー対話モードになっています。

運用環境で IIS にデプロイした時は、(1) はデフォルトでは Network Service または AppPoolIdentity という権限が低いアカウント、(2) は非ユーザー対話モードです。

ユーザー対話モードにならないということは、ユーザーが対話するためのグラフィカルユーザーインターフェイスが存在しないということで、モーダルダイアログやメッセージボックスは表示できません。

ワーカープロセスのアカウントは WindowsIdentity.GetCurrent メソッドで、ユーザー対話モードで実行されているか否かは Environment.UserInteractive プロパティで調べることができます。上の画像の赤枠部分が Windows 10 の IIS 10 でホストされる ASP.NET Web Forms アプリで調べた結果です。

上記 (1) の権限の問題は、Network Service または AppPoolIdentity に必要な権限を与えるとか、権限を持つアカウントを偽装するとかで解決します。

または、以下の画像のように IIS Manager を操作して、プロセスモデルの ID に必要な権限を持つユーザーアカウントを設定することでも解決できます。

ワーカープロセスのアカウント変更

しかし、(2) のユーザー対話モードについてはそれでは何ともなりません。ユーザー対話モードにする手段は少なくとも自分が調べた限りでは無かったです。

実は、上の画像のようにプロセスモデルの ID に管理者権限を持つユーザーアカウントを設定すれば Environment.UserInteractive が True(=ユーザー対話モード)になると思い違いしていました。

昔�� Teratail のスレッド「WebBrowserの動作に影響するPC環境の相違点」に回答する際調べたことなのですが、すっかり忘れていたので備忘録として残しておくことにした次第です。

Tags: , ,

ASP.NET

Multiple Active Result Sets (MARS)

by WebSurfer 15. September 2022 19:24

SQL Server の Multiple Active Result Sets (MARS) というのは何で、どのような場合に必要かという話を書きます。

MARS は SQL Server 2005 以降で利用できる機能で、Microsoft のドキュメント「複数のアクティブな結果セットの有効化」によると "複数のバッチを単一の接続で実行することができます" ということです。(分かりやすい説明を下の方に追記)

接続文字列で MultipleActiveResultSets を true に設定することにより利用できます。

.NET Framework 2.0 からサポートされていたのですが、昔はそのような設定を見かけることは無かったです。それが ADO.NET Entity Data Model ウィザードで自動生成される接続文字列などに設定されるのを見かけて、なぜだろうと疑問に思っていました。

接続文字列で MultipleActiveResultSets=True として「複数のアクティブな結果セットの有効化」を行った例を以下に書きます。

string connString1 = "Data Source=lpc:(local)\\sqlexpress;" +
                     "Initial Catalog=NORTHWIND;" +
                     "Integrated Security=True;" +
                     "MultipleActiveResultSets=True";

string query1 = "SELECT CategoryID, CategoryName FROM Categories;";
string query2 = "SELECT ProductID, ProductName FROM Products;";

using (var connection = new SqlConnection(connString1))
{
    connection.Open();
    using (var command = new SqlCommand(query1, connection))
    {
        SqlDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            Console.WriteLine("\t{0}\t{1}",
                reader.GetInt32(0), reader.GetString(1));
        }
    }

    using (var command = new SqlCommand(query2, connection))
    {
        SqlDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            Console.WriteLine("\t{0}\t{1}",
                reader.GetInt32(0), reader.GetString(1));
        }
    }
}

MARS はデフォルトでは無効になっており、その場合はアプリケーションはバッチごとにすべての結果セットを処理またはキャンセルしないと、同じ接続で他のバッチを実行できません。

どういうことかと言うと、接続文字列の MultipleActiveResultSets=True を削除すると 2 つ目の command.ExecuteReader() で以下のように例外がスローされます。

DataReader エラー

上のコードでは、MARS の設定なしでも、DataReader を閉じるコードを書けば例外は回避できるのですが、Entity Framework が問題です。

例えば、Entity Framework の「遅延読み込み」を行ったりすると、MARS の設定無しでは以下の画像のように例外がスローされます。

遅延読み込み時のエラー

ADO.NET Entity Data Model ウィザードなどで自動生成される接続文字列に MARS の設定が含まれているのはそういう理由であろうと思われます。


2022/9/28 追記

MSDN ライブラリ Visual Studio 2008 の SqlCommand.ExecuteReader メソッドの解説に MARS の分かりやすい説明があるのを見つけましたので以下に書いておきます。

"SQL Server 2005 より前のバージョンの SQL Server の場合、SqlDataReader が使用されている間、関連付けられている SqlConnection は SqlDataReader によって使用されるため、ビジー状態になります。この状態では、SqlConnection に対して、閉じる以外の操作を実行できません。SqlDataReader の Close メソッドを呼び出すまでこの状態が続きます。SQL Server 2005 では、MARS (Multiple Active Result Set) 機能がサポートされ、同一接続を使用して複数の処理を実行できるようになりました"

Tags: , ,

ADO.NET

About this blog

2010年5月にこのブログを立ち上げました。その後ブログ2を追加し、ここはプログラミング関係、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  October 2022  >>
MoTuWeThFrSaSu
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar