Symfoware

Symfowareについての考察blog

Debian 8(jessie) + C#(Mono)でSQL Server 2016に接続する

Debian 6 + Monoでも同様のことをやったことがあるのですが、改めて試してみます。
Debian(Squeeze) + MonoでSQL Serverに接続する


Monoのインストールはこちら。
Debian 8(jessie)にapt-getでmonoをインストール

SQL Server 2016は外部から接続可能なように構成しておきます。
Windows Server 2016のポートを開放する(SQL Server 2016 外部接続許可)




DebianとMonoのバージョン



実行時のDebianやMonoのバージョンです。


# cat /etc/debian_version
8.6

# uname -a
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux

# mono -V
Mono JIT compiler version 4.6.1 (Stable 4.6.1.3/abb06f1 Wed Sep 28 13:54:26 UTC 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
    TLS:         __thread
    SIGSEGV:     altstack
    Notifications: epoll
    Architecture: amd64
    Disabled:     none
    Misc:         softdebug
    LLVM:         supported, not enabled.
    GC:            sgen




Debian 8.6、Mono 4.6.1の環境です。





テストデータベース



IP : 192.168.1.104
User ID : sa
Password : P@ssw0rd

sampleというデータベースにt1というテーブルを作成しました。
idがint型、valueがvarchar型です。

713_01.png




データの登録



簡単なデータの登録プログラムはこんな感じになります。


  1. using System;
  2. using System.Data;
  3. using System.Data.SqlClient;
  4. public class Sample {
  5.     
  6.     static public void Main () {
  7.         
  8.         // 接続文字列
  9.         string connectString = "Data Source=192.168.1.104;";
  10.         connectString += "Initial Catalog=sample;";
  11.         connectString += "User ID=sa;";
  12.         connectString += "Password=P@ssw0rd;";
  13.         connectString += "Trusted_Connection=False;";
  14.         
  15.         // データベースに接続
  16.         using (SqlConnection con = new SqlConnection(connectString)) {
  17.             
  18.             // 登録実行
  19.             string query = "INSERT INTO t1 (id, value) VALUES (1, 'C#から登録テスト')";
  20.             
  21.             con.Open();
  22.             SqlCommand cmd = new SqlCommand(query, con);
  23.             cmd.ExecuteNonQuery();
  24.             
  25.         }
  26.         
  27.     }
  28. }




コンパイル時、「-r:System.Data.dll」を付与してSystem.Data名前空間が使用できるようにします。


# mcs sample.cs -r:System.Data.dll




付けていないと、こんなエラーが発生します。


sample.cs(2,14): error CS0234: The type or namespace name `Data' does not exist in the namespace `System'.
Are you missing `System.Data' assembly reference?




プログラムを実行すると、ちゃんとデータが登録されていました。

713_02.png





SqlDataAdapterを使用したデータの検索



今度は登録したデータを検索してみます。


  1. using System;
  2. using System.Data;
  3. using System.Data.SqlClient;
  4. public class Sample {
  5.     
  6.     static public void Main () {
  7.         
  8.         // 接続文字列
  9.         string connectString = "Data Source=192.168.1.104;";
  10.         connectString += "Initial Catalog=sample;";
  11.         connectString += "User ID=sa;";
  12.         connectString += "Password=P@ssw0rd;";
  13.         connectString += "Trusted_Connection=False;";
  14.         
  15.         // データベースに接続
  16.         using (SqlConnection con = new SqlConnection(connectString)) {
  17.             
  18.             using (SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM t1", con))
  19.             using (DataTable dt = new DataTable()) {
  20.                 
  21.                 // 検索結果をDataTableに退避
  22.                 da.Fill(dt);
  23.                 
  24.                 // 内容を表示
  25.                 foreach (DataRow dr in dt.Rows) {
  26.                     Console.WriteLine("id:{0}, value:{1}", dr["id"], dr["value"]);
  27.                 }
  28.                 
  29.             }
  30.             
  31.         }
  32.         
  33.     }
  34. }




実行結果


# ./sample.exe
id:1, value:C#から登録テスト




ちゃんとデータが取得できていますね。





SqlDataAdapterを使用したデータの登録



SqlDataAdapterを使用してデータの更新が行えるのは知っていたのですが、
試したことがなかったのでやってみます。

Mono特有なのかもしれませんが、こんなエラーが発生して苦しみました。


-- 更新用のクエリーが設定されていない
Unhandled Exception:
System.InvalidOperationException: Update requires a valid UpdateCommand when passed DataRow collection with modified rows.


-- 更新用のクエリーのコネクションが初期化されていない
Unhandled Exception:
System.InvalidOperationException: Update requires the command clone to have a connection object.
The Connection property of the command clone has not been initialized.


Unhandled Exception:
System.InvalidOperationException: Update requires the UpdateCommand to have a connection object.
The Connection property of the UpdateCommand has not been initialized.





最終的に、データの追加や更新を行うプログラムはこうなりました。


  1. using System;
  2. using System.Data;
  3. using System.Data.SqlClient;
  4. public class Sample {
  5.     
  6.     static public void Main () {
  7.         
  8.         // 接続文字列
  9.         string connectString = "Data Source=192.168.1.104;";
  10.         connectString += "Initial Catalog=sample;";
  11.         connectString += "User ID=sa;";
  12.         connectString += "Password=P@ssw0rd;";
  13.         connectString += "Trusted_Connection=False;";
  14.         
  15.         // データベースに接続
  16.         using (SqlConnection con = new SqlConnection(connectString)) {
  17.             
  18.             using (SqlDataAdapter da = new SqlDataAdapter())
  19.             using (DataTable dt = new DataTable()) {
  20.                 
  21.                 da.SelectCommand = new SqlCommand("SELECT * FROM t1", con);
  22.                 SqlCommandBuilder builder = new SqlCommandBuilder(da);
  23.                 
  24.                 con.Open();
  25.                 
  26.                 // 検索結果をDataTableに退避
  27.                 da.Fill(dt);
  28.                 
  29.                 
  30.                 // 削除クエリー準備
  31.                 da.DeleteCommand = builder.GetDeleteCommand(true);
  32.                 da.DeleteCommand.Connection = con;
  33.                 
  34.                 // 更新クエリー準備
  35.                 da.UpdateCommand = builder.GetUpdateCommand(true);
  36.                 da.UpdateCommand.Connection = con;
  37.                 
  38.                 // 登録クエリー準備
  39.                 da.InsertCommand = builder.GetInsertCommand(true);
  40.                 da.InsertCommand.Connection = con;
  41.                 
  42.                 
  43.                 // 1行目のデータを更新
  44.                 dt.Rows[0]["value"] = "C#からデータ更新";
  45.                 
  46.                 // 新しい行の挿入
  47.                 DataRow dr = dt.NewRow();
  48.                 dr["id"] = 2;
  49.                 dr["value"] = "新しい行を追加";
  50.                 dt.Rows.Add(dr);
  51.                 
  52.                 // 行の更新と追加を実行
  53.                 da.Update(dt);
  54.             }
  55.             
  56.         }
  57.         
  58.     }
  59. }




実行してみると、ちゃんとデータの更新と追加が行われています。

713_03.png



【参考URL】

DataAdapter.Update() does not Update the Database

Update requires a valid InsertCommand when passed DataRow collection with new rows

SqlCommandBuilder クラス



関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2016/10/04(火) 23:05:23|
  2. SQL Server
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<C#(mono)DataTableのフィールド値をキーにDictionaryへ変換 | ホーム | C# LINQ の使い方(Select, Where, OrderBy, OrderByDescending, Aggregate)>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1929-a2c9d849
この記事にトラックバックする(FC2ブログユーザー)