DBへの問い合わせにはDLinqというキーワードで色々調べればいいんだって。
ってことで調べてみたよ。
まず、DBを用意しないと始まらないのでSQL Server 2005 Express Editionで下の絵のようなテーブルを作ったよ。
中身のデータは以下のようなものを詰め込んどいたよ。
ID | Name |
1 | 太郎 |
2 | 二郎 |
3 | 三郎 |
4 | 四郎 |
5 | 五郎 |
DLinqで使うためのクラスは、ツールが自動生成してくれるみたいだ。
SqlMetal.exeというものらしいよ。
どこにあるのか検索してみたら、Visual Studio OrcasのインストールフォルダのSDK\v3.5\Binにあったよ。
とりあえず、毎回長いパスをうつのがめんどくさいからパスを通しておいた。
sqlmetalとだけ打ち込むと使い方が出てくる。
Sqlmetal [options] [<input file>] options: /server:<name> Database server name /database:<name> Database catalog on server /user:<name> Login user ID /password:<name> Login password /views Extract database views /functions Extract database functions /sprocs Extract stored procedures /xml[:file] Output as DBML /code[:file] Output as source code /map[:file] Generate XML mapping file instead of attributes /language:xxx Language for source code (vb,csharp) /namespace:<name> Namespace used for source code /pluralize Auto-pluralize table names /serialization:xxx Generate serializable classes (None, Unidirectional) /timeout:<seconds> Timeout value in seconds to use for database commands examples: To generate a .dbml file with extracted SQL metadata. Sqlmetal /server:myserver /database:northwind /xml:mymeta.dbml To generate a .dbml file with extracted SQL metadata from an .mdf file. Sqlmetal /xml:mymeta.dbml mydbfile.mdf To generate source code from a .dbml metadata file. Sqlmetal /namespace:nwind /code:nwind.cs /language:csharp mymetal.dbml To generate source code from SQL metadata directly. Sqlmetal /server:myserver /database:northwind /namespace:nwind /code:nwind.cs /language:csharp
色々出てるけど、最後の奴を自分の環境に置き換えてやればよさそうだね。
ということで自分の環境だと下のようにうつとうまくいったよ。
sqlmetal /server:KAZUKI-PC\SQLEXPRESS /database:EDU /namespace:DLinqSample /code:DLinqSample.cs /language:csharp
これでDLinqSample.csが出来上がるから、Visual Studioで作ったプロジェクト(お試しなのでコンソールにしたよ)に追加してビルドしてみるとコンパイルエラーが出ちゃった。
どうやらSystem.Data.Linqを参照に追加しないといけないようだ。
参照を追加したらビルドが通ったので、下のようなプログラムを書いてみたよ。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DLinqSample { class Program { static void Main(string[] args) { EDU edu = new EDU(@"Server=KAZUKI-PC\SQLEXPRESS;Database=EDU;Integrated Security=true"); IEnumerable<Employees> emps = from emp in edu.Employees where emp.ID % 2 == 0 select emp; foreach (Employees emp in emps) { Console.WriteLine("{0}: {1}", emp.ID, emp.Name); } } } }
EDUってのは、さっきツールが自動生成してくれたクラスだよ。
これに対して接続文字列かIDbConnectionを渡すことが出来る。
今回は接続文字列を直接指定したよ。
実行してみると、↓みたいな結果だったよ。
2: 二郎 4: 四郎
うん。ちゃんと動いてる。
もう少しだけ踏み込んでみるね。
EDUクラスの親クラスはSystem.Data.Linq.DataContextなんだけど、そいつにはLogってプロパティがあるんだ。
TextWriterを受け取るみたいなので、Console.Outを渡すように書き換えてみたよ。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DLinqSample { class Program { static void Main(string[] args) { EDU edu = new EDU(@"Server=KAZUKI-PC\SQLEXPRESS;Database=EDU;Integrated Security=true"); edu.Log = Console.Out; Console.WriteLine("Before LINQ"); IEnumerable<Employees> emps = from emp in edu.Employees where emp.ID % 2 == 0 select emp; Console.WriteLine("After LINQ"); foreach (Employees emp in emps) { Console.WriteLine("{0}: {1}", emp.ID, emp.Name); } } } }
LINQの直前と直後に目印のログを吐くように仕込んで実行してみたよ。
Before LINQ After LINQ SELECT [t0].[ID], [t0].[Name] FROM [Employees] AS [t0] WHERE ([t0].[ID] % @p0) = @p1 -- @p0: Input Decimal (Size = 0; Prec = 29; Scale = 4) NOT NULL [2] -- @p1: Input Decimal (Size = 0; Prec = 29; Scale = 4) NOT NULL [0] SqlProvider\AttributedMetaModel 2: 二郎 4: 四郎
うん。何か思ったのと出力順が違うね。
DLINQは、必要になった時点ではじめてDBにアクセスしにいくっぽい。
ここら辺の動きをおさえておかないと、何かはまっちゃうかもしれないね。
でも、今日はここまで。