【VB.NET】LINQ友の会【C#, C♯, C#】

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2008/02/09(土) 23:51:34
VisualStudio2008より追加された便利で強力な機能

  統合言語クエリ (LINQ : Language Integrated Query)

ちょっと使ってみると、意外と難しいし、テクニック的にも奥が深いものです。
関数型言語にしかないような機能ラムダ式(Lambda式)などはオブジェクト指向とは一味違う機能です。
DataBaseの操作にも、Xmlの操作にも、さらにもっと単純な配列なコンテナにさえ機能する
言語共通・高汎用な統合言語クエリを皆で一緒にマターリ勉強しましょう。
質問、便利なマイテクニックの発表、いろいろやっちゃってください。
2デフォルトの名無しさん
垢版 |
2008/02/09(土) 23:52:34
>>1 もこれから使い始めます、答えられそうな質問にはどんどん答えます、無理なのは……誰かお願い。
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);

とてもすっきりかけます。
2008/02/10(日) 00:20:06
部分的にSQLがかけますよ、って感じか
どーなんだろ、便利か?これ
2008/02/10(日) 00:25:18
まあ、便利なんだろうけど、あまり優秀でないプログラマに使わせるとこんな記述が
そこらじゅうにばら撒かれたきわめて保守し辛いプログラムが量産されるような気が
する。
2008/02/10(日) 00:34:33
もう全部の言語合体したのを作っちゃいなよw

CLR自体に新しい何かが加わったの?
.NET層のインターフェイス?
シンタックスシュガーにも見えなくもない。
全然c#に触れてないので見当違いなこと言ってたらごめんよ。
2008/02/10(日) 00:53:14
>>6
ラムダ式のシンタックスシュガーですよ、かなりなんでも出来ます。
2008/02/10(日) 00:55:57
明日は、とりあえず難しい事考えなくても、簡単に使えるサンプルでも考えてみるかな・・・
2008/02/10(日) 01:15:38
洋書だとC#3の本がかなり出てるらしいけど、日本語のはぜんぜんでないな。
2008/02/10(日) 07:20:46
何が便利かって、グループ化の機能が便利だ。
11762
垢版 |
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で遊んでみた
2008/02/11(月) 15:15:26
データベースからデータを拾ってきて、LocationID が 10 未満の行を取り出すサンプル。
従来コードから徐々に LINQ に書き換えて行って見ました。
データは、Microsoft SQL Server 2005 に最初から入っているものです。
こちらの使用環境は Professional エデッションで、二枚付いているディスクはフルインストール
ウインドウズ認証でインストールして特に変わった設定がしてなければ、"貴方のPC" を自分のPC名に書き換えれば動くと思います、多分。
データベースは、最初から入っているサンプルデータ AdventureWorks の中の Location(Production) を使ってみました。
DataGridView コントロールを二つ貼り付けて、ボタンを一つ用意して、ボタンプッシュのイベントで実行しています。
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
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;
}
}
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;
}
}
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;
}
}
■ このスレッドは過去ログ倉庫に格納されています