射撃しつつ前進する方への援護射撃です。
群馬に行った時、データセットの件で「う~ん」と思い、なんとなく落とし穴に陥りそうな匂いはしていたのですが、時間が取れずにそのままに。
という訳で遅ればせながら、.NET(C#)でMySQLを扱うときのコツなんかを、詳しめに書いておきます。
■接続方法はADO.NET Driver for MySQL (Connector/NET)を使う
まず、.NETから扱えるように下記をダウンロードしてインストールします。
MySQL :: Download Connector/Net
http://www-jp.mysql.com/downloads/connector/net/
■名前空間は MySql.Data.MySqlClient
SQL Server の場合は System.Data.SqlClient を使いますが、MySQL の場合は MySql.Data.MySqlClient をインポートします。
C# だったら先頭の行に
using MySql.Data.MySqlClient;
でOK
■主なクラス
ADO.NET経由でSQL Serverを扱う場合は、
コネクション SqlConnect
アダプタ SqlDataAdapter
となっています。
これが MySQL の場合は
コネクション MySqlConnect
アダプタ MySqlDataAdapter
となればOK。
巷のADO.NETのサンプルもこれを書き換えれば大抵動きます。
肝心のDataSet、DataTable クラスに関しては、SQL Serverでも MySQL でも同じものを使います。最初のコネクションとアダプタの名前が違うだけです。使い方は統一されているので、クラス名だけ変えれば普通は通ります。

■サンプル
いわゆる、こんな画面を作ってデータ接続をテストすると場合
サンプルコードはこちら
// クリアボタン
private void button1_Click(object sender, EventArgs e)
{
// 挿入時のクリア
dataGridView1.Columns.Clear();
// バインド時
dataGridView1.DataSource = null;
}
// DataSetボタン
private void button2_Click(object sender, EventArgs e)
{
// コネクション作成
MySqlConnection cn = new MySqlConnection(
“Data Source=localhost;Database=konicadb;User ID=konica;password=konica”);
MySqlDataAdapter da = new MySqlDataAdapter(
“SELECT * FROM sample”, cn);
DataTable dt = new DataTable();
// 検索
da.Fill(dt);
// 表示
dataGridView1.DataSource = dt;
// データ保持
m_dt = dt;
}
///
/// データ保持用
///
DataTable m_dt;
// DataSet自前ボタン
private void button3_Click(object sender, EventArgs e)
{
// コネクション作成
MySqlConnection cn = new MySqlConnection(
“Data Source=localhost;Database=konicadb;User ID=konica;password=konica”);
MySqlDataAdapter da = new MySqlDataAdapter(
“SELECT * FROM sample”, cn);
DataTable dt = new DataTable();
// 検索
da.Fill(dt);
// 自前で表示
dataGridView1.Columns.Add(“ID”, “ID”);
dataGridView1.Columns.Add(“name”, “名前”);
foreach (DataRow item in dt.Rows)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = item["id"];
dataGridView1.Rows[n].Cells[1].Value = item["name"];
}
}
// 保存済みのDataSetボタン
private void button4_Click(object sender, EventArgs e)
{
// 表示
dataGridView1.DataSource = m_dt;
}
// LINQは動かせない
private void button5_Click(object sender, EventArgs e)
{
// これはSQL Serverしかできない
string cnstr = “Data Source=localhost;Database=konicadb;User ID=konica;password=konica”;
DataContext dc = new DataContext(cnstr);
var tb = dc.GetTable();
dataGridView1.DataSource = tb;
}
[TableAttribute(Name = "sample")]
public class TSample
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime UpdateDate { get; set; }
}
データグリッドで表示するだけならば、DataSourceプロパティを使ったほうが簡単です。列名なんかが固定であれば、デザイン時に表示する文字列を入れて、バインドする列名を入れておけばOK。
DataSet(ここではDataTable)の使いどころは、保存済みのDataSetボタンのところのように、一度キープしたものをデータベースに接続せずに使えることですね。いわゆるキャッシュの役割です。
当然、DataSetに一時的に更新状態をキープして、一気にデータベースにコミット、という流れもできるんですが、型付きDataSetを作らないと効率的でないので、最初は避けたほうがよいかなと思っています。MySqlCommand を使って、ちまちま INSERT文やUPDATE文を書いたほうが、後々の見通しが良くなります(経験上ですが)。
■DataSetとは何ぞや?
という訳で、DataSetとは何ぞやを、もうちょっと。
最初にデータベース接続に関しては歴史的に、
- ODBC接続
- RDO,DAO,ADO
- ADO.NET, DataSet
- ADO.NET, 型付きDataSet
- LINQ to SQL
- ADO.NET Data Entity
な流れがあります。
ODBC接続は、SQL文を流してちまちまと受け取る方法ですね。Oracleで埋め込み型のPL/SQLを使っているとカーソルを使ったり、フェッチを使ったりとややこしいことこの上ないのですが、C言語からモロ扱えるしろものです。今でも結構やります。
これじゃあ、大変という訳でRDO,DAO,ADOなんてのが出来ました。
主にVBやExcel VBAから使っていたもので、接続する方法をCOM/ActiveXなんかで扱えるようになっています。VB6ぐらいにはお世話になったものです。VB6自体は本格的なオブジェクト指向言語ではない(一部、クラスが使えますが)ので、C++で作成したActiveXを使うという形で、「オブジェクト」を扱うん出うのです。
これを VC++で使っていたりしました。
この最終形のADO(ActiveX Data Objects)の.NET版が、ADO.NETです。
最初は、ADOの移植版という形。
その中でDataSetというのが、データキャッシュの役割を持ちます。
おそらく当時、ASP.NETを作った関係で、WEBサイトのキャッシュをする必要があってのDataSetかなぁ、と。
最初、DataSetは型がない(列名を持たない)ので、アクセスするときのパフォーマンスが落ちました。また、C#のような厳密にメンバを指定したい場合なんかは、文字列で列名を書くのはちょっと...な感じでした(Row["name"]みたいなの)。
これを、Tsample.name のようにプロパティ名にしたいなぁ、と思ったのが型付きDataSetの始まりです。
この型付の話は、当時、データベースとオブジェクト指向を繋げるという意味で、「O/Rマッピング」と言われています。今では、この手の自動生成ツール(Ruby on Railsとか)が主流になりましたが、その最初の頃ってな感じです。
O/Rマッピングが流行って、データベースからクラスのコードを自動生成してくるのに慣れてくると、一方で SQL 文をプログラマが書かなくなったんですね。自前のデータアクセス方法を提案し始めたというところです。
それが、LINQであったり、という訳で、LINQ to SQL なんかがあります。
LINQ自体は、データベースに限らないのですが、まあ、関数言語の良いとこ取りな感じで。
一方で、ADO.NET Data Entity というのがあって、これがDataSetの正式な子供ですね。Visual Studio でデータベースに接続して、データクラスを自動生成してってやり方です。
このような流れの中で、MySQL は
- ADO.NET, 型付きDataSet
- LINQ to SQL
- ADO.NET Data Entity
のところが使えません。厳密には型付きDataSetは使えるのですが、ちまちまと自前で作らないといけないので、メンテ上非常に大変(それを上回る保守コストならば別ですが)。
なので、MySQL+.NETという組み合わせでは、MySQLのConnectorを使って DataSet/DataTable を使うのが定番かと思います。
■DataSetの使いどころ
MSさんの宣伝記事ならば、
DataSetで、複数のデータ更新ができるのでデータベースに直結せずに、全てのCRUD処理をDataSetを媒介したほうが効率が良い。

と言いたいところなのですが、現場レベルとしては、ちょっと困るところが出てきます。
1)複数のテーブルが連携しているときの処理が分かりずらい。
2)大量のデータを更新中に、DataSet内で止まってしまう。
のようなお困りが発生します。
1)のほうは、マスターテーブルのような単純なテーブルに関しては DataSet/DataTable を使うと非常に早く更新ができるので楽です。
ですが、他のテーブルのリレーションがあった場合、同時更新などで別のキーを参照する場合の時は、コミットする前の場合、DataSet内のテーブルを探らないと駄目なので、この処理が非常に面倒です。なので、この場合は、トランザクションを付けて、直接データベースにアクセスしたほうが楽にコーディングができます。
2)のほうは、致命的なところがあって、データ量が非常に多くなる(1万件など)場合は、DataSet自体のメモリが大きくなると同時に、更新時にいちいちデータのチェックが走るので、結構重たい処理になってしまいます。この更新処理をDataSet内部のコードを弄って、分割したりするよりは、素直に更新時は直接データベースにアクセスにしに行ったほうがすっきりしたコードが書けます。
という訳で、実際はこんな風に使います。

ええ、なんか見たことがある矢印の向きですよね。

こんな風に、MVCスタイルにするとコードが見やすくなります。
つまり、コントローラ部分を分離させた方が、コードの見通しが良くなる、という予想が立ちます(実際、そうなります)。






おお、感謝(´・ω・)ス
早速内容視姦して再度理解してみるです。
本当にデータベース絡み・・・しっかり覚えないですね。