1 名前:デフォルトの名無しさん [2008/02/09(土) 23:51:34 ] VisualStudio2008より追加された便利で強力な機能 統合言語クエリ (LINQ : Language Integrated Query) ちょっと使ってみると、意外と難しいし、テクニック的にも奥が深いものです。 関数型言語にしかないような機能ラムダ式(Lambda式)などはオブジェクト指向とは一味違う機能です。 DataBaseの操作にも、Xmlの操作にも、さらにもっと単純な配列なコンテナにさえ機能する 言語共通・高汎用な統合言語クエリを皆で一緒にマターリ勉強しましょう。 質問、便利なマイテクニックの発表、いろいろやっちゃってください。
2 名前:デフォルトの名無しさん [2008/02/09(土) 23:52:34 ] >>1 もこれから使い始めます、答えられそうな質問にはどんどん答えます、無理なのは……誰かお願い。
3 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 00:05:21 ] まずは一発目 LINQってなあに、という所で、これは以下のような事ができます。 このコードは配列から4以下の値を取り出します。 int [] data = new int[] { 3, 1, 4, 1, 5, 9, 2, 6 }; IEnumerable<int> x = from s in data where s <= 4 select s; foreach (int ite in x) System.Console.Write( "{0}," , ite); 3,1,4,1,2, これを、ちょっと短くしてみる。 int [] data = new int[] { 3, 1, 4, 1, 5, 9, 2, 6 }; foreach (int ite in from s in data where s <= 4 select s) System.Console.Write( "{0}," , ite); とてもすっきりかけます。
4 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 00:20:06 ] 部分的にSQLがかけますよ、って感じか どーなんだろ、便利か?これ
5 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 00:25:18 ] まあ、便利なんだろうけど、あまり優秀でないプログラマに使わせるとこんな記述が そこらじゅうにばら撒かれたきわめて保守し辛いプログラムが量産されるような気が する。
6 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 00:34:33 ] もう全部の言語合体したのを作っちゃいなよw CLR自体に新しい何かが加わったの? .NET層のインターフェイス? シンタックスシュガーにも見えなくもない。 全然c#に触れてないので見当違いなこと言ってたらごめんよ。
7 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 00:53:14 ] >>6 ラムダ式のシンタックスシュガーですよ、かなりなんでも出来ます。
8 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 00:55:57 ] 明日は、とりあえず難しい事考えなくても、簡単に使えるサンプルでも考えてみるかな・・・
9 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 01:15:38 ] 洋書だとC#3の本がかなり出てるらしいけど、日本語のはぜんぜんでないな。
10 名前:デフォルトの名無しさん mailto:sage [2008/02/10(日) 07:20:46 ] 何が便利かって、グループ化の機能が便利だ。
11 名前:762 mailto:sage [2008/02/10(日) 12:42:26 ] static T Multiply<T>(T left, T right) { var r = Expression.Parameter(typeof(T), "left"); var l = Expression.Parameter(typeof(T), "right"); return Expression.Lambda<Func<T, T, T>>(Expression.Multiply(r, l), l, r).Compile()(left, right); } Expression Treeで遊んでみた
12 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 15:15:26 ] データベースからデータを拾ってきて、LocationID が 10 未満の行を取り出すサンプル。 従来コードから徐々に LINQ に書き換えて行って見ました。 データは、Microsoft SQL Server 2005 に最初から入っているものです。 こちらの使用環境は Professional エデッションで、二枚付いているディスクはフルインストール ウインドウズ認証でインストールして特に変わった設定がしてなければ、"貴方のPC" を自分のPC名に書き換えれば動くと思います、多分。 データベースは、最初から入っているサンプルデータ AdventureWorks の中の Location(Production) を使ってみました。 DataGridView コントロールを二つ貼り付けて、ボタンを一つ用意して、ボタンプッシュのイベントで実行しています。
13 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 15:16:32 ] 続き(>>12 ) 次のように変換されます。 1 Tool Crib 0.0000 0.00 1998/06/01 2 Sheet Metal Racks 0.0000 0.00 1998/06/01 3 Paint Shop 0.0000 0.00 1998/06/01 4 Paint Storage 0.0000 0.00 1998/06/01 5 Metal Storage 0.0000 0.00 1998/06/01 6 Miscellaneous Storage 0.0000 0.00 1998/06/01 7 Finished Goods Storage 0.0000 0.00 1998/06/01 10 Frame Forming 22.5000 96.00 1998/06/01 20 Frame Welding 25.0000 108.00 1998/06/01 30 Debur and Polish 14.5000 120.00 1998/06/01 40 Paint 15.7500 120.00 1998/06/01 45 Specialized Paint 18.0000 80.00 1998/06/01 50 Subassembly 12.2500 120.00 1998/06/01 60 Final Assembly 12.2500 120.00 1998/06/01 ↓ 1 Tool Crib 0.0000 0.00 1998/06/01 2 Sheet Metal Racks 0.0000 0.00 1998/06/01 3 Paint Shop 0.0000 0.00 1998/06/01 4 Paint Storage 0.0000 0.00 1998/06/01 5 Metal Storage 0.0000 0.00 1998/06/01 6 Miscellaneous Storage 0.0000 0.00 1998/06/01 7 Finished Goods Storage 0.0000 0.00 1998/06/01
14 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 15:17:26 ] 続き(>>13 ) // 従来方式 private void Test4() { using (System.Data.SqlClient.SqlDataAdapter myDataAdapter = new System.Data.SqlClient.SqlDataAdapter("select * from Production.Location", "Data Source=貴方のPC;Initial Catalog=AdventureWorks;Integrated Security=True")) { // サンプルデータベースからデータを取り込む System.Data.DataTable dataTable1 = new System.Data.DataTable(); myDataAdapter.Fill(dataTable1); // LocationIDが10以下の行のみのテーブルを作る System.Data.DataTable dataTable2 = dataTable1.Clone(); foreach (System.Data.DataRow tmp1 in dataTable1.Select("LocationID < 10")) { System.Data.DataRow tmp2 = dataTable2.NewRow(); tmp2.ItemArray = tmp1.ItemArray; dataTable2.Rows.Add(tmp2); } // ためしに表示 this.dataGridView1.DataSource = dataTable1; this.dataGridView2.DataSource = dataTable2; } }
15 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 15:18:11 ] 続き(>>14 ) // var を使ったバージョン private void test5() { using (var myDataAdapter = new System.Data.SqlClient.SqlDataAdapter("select * from Production.Location", "Data Source=貴方のPC;Initial Catalog=AdventureWorks;Integrated Security=True")) { // サンプルデータベースからデータを取り込む var dataTable1 = new System.Data.DataTable(); myDataAdapter.Fill(dataTable1); // LocationIDが10以下の行のみのテーブルを作る var dataTable2 = dataTable1.Clone(); foreach (var tmp1 in dataTable1.Select("LocationID < 10")) { var tmp2 = dataTable2.NewRow(); tmp2.ItemArray = tmp1.ItemArray; dataTable2.Rows.Add(tmp2); } // ためしに表示 this.dataGridView1.DataSource = dataTable1; this.dataGridView2.DataSource = dataTable2; } }
16 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 15:19:25 ] 続き(>>15 ) // LINQ を使ったバージョン(意味が解りやすいように型付き) private void Test7() { using (System.Data.SqlClient.SqlDataAdapter myDataAdapter = new System.Data.SqlClient.SqlDataAdapter("select * from Production.Location", "Data Source=貴方のPC;Initial Catalog=AdventureWorks;Integrated Security=True")) { // サンプルデータベースからデータを取り込む System.Data.DataTable dataTable1 = new System.Data.DataTable(); myDataAdapter.Fill(dataTable1); // LocationIDが10以下の行のみのテーブルを作る EnumerableRowCollection<System.Data.DataRow> query = from tmp2 in dataTable1.AsEnumerable() where tmp2.Field<short>("LocationID") < 10 select tmp2; System.Data.DataTable dataTable2 = query.CopyToDataTable(); // ためしに表示 this.dataGridView1.DataSource = dataTable1; this.dataGridView2.DataSource = dataTable2; } }
17 名前:デフォルトの名無しさん [2008/02/11(月) 15:25:03 ] 続き(>>16 ) 最後 // LINQ を使ったバージョン private void Test8() { using (var myDataAdapter = new System.Data.SqlClient.SqlDataAdapter("select * from Production.Location", "Data Source=貴方のPC;Initial Catalog=AdventureWorks;Integrated Security=True")) { // サンプルデータベースからデータを取り込む var dataTable1 = new System.Data.DataTable(); myDataAdapter.Fill(dataTable1); // LocationIDが10以下の行のみのテーブルを作る var tmp1 = from tmp2 in dataTable1.AsEnumerable() where tmp2.Field<short>("LocationID") < 10 select tmp2; var dataTable2 = tmp1.CopyToDataTable(); // ためしに表示 this.dataGridView1.DataSource = dataTable1; this.dataGridView2.DataSource = dataTable2; } }