VisualStudio2008より追加された便利で強力な機能
統合言語クエリ (LINQ : Language Integrated Query)
ちょっと使ってみると、意外と難しいし、テクニック的にも奥が深いものです。
関数型言語にしかないような機能ラムダ式(Lambda式)などはオブジェクト指向とは一味違う機能です。
DataBaseの操作にも、Xmlの操作にも、さらにもっと単純な配列なコンテナにさえ機能する
言語共通・高汎用な統合言語クエリを皆で一緒にマターリ勉強しましょう。
質問、便利なマイテクニックの発表、いろいろやっちゃってください。
探検
【VB.NET】LINQ友の会【C#, C♯, C#】
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2008/02/09(土) 23:51:342デフォルトの名無しさん
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);
とてもすっきりかけます。
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#に触れてないので見当違いなこと言ってたらごめんよ。
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で遊んでみた
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 コントロールを二つ貼り付けて、ボタンを一つ用意して、ボタンプッシュのイベントで実行しています。
従来コードから徐々に 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
次のように変換されます。
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;
}
}
// 従来方式
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;
}
}
// 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;
}
}
// 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;
}
}
// 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;
}
}
2008/02/11(月) 15:28:13
さて、次はLINQ to Sql にいくか、それともしょうもない内容にすべか
誰も来なければそろそろ諦めるかw
誰も来なければそろそろ諦めるかw
2008/02/11(月) 17:33:56
LINQ: .NET 統合言語クエリ
http://www.microsoft.com/japan/msdn/net/bb308959.aspx
Part4 LINQで変わるデータベース開発:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20080116/291140/?P=1&ST=develop
スレ立てるの早すぎだと思われ
然程使ってもいないのに意見の交換なんて出来ませぬ
http://www.microsoft.com/japan/msdn/net/bb308959.aspx
Part4 LINQで変わるデータベース開発:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20080116/291140/?P=1&ST=develop
スレ立てるの早すぎだと思われ
然程使ってもいないのに意見の交換なんて出来ませぬ
2008/02/11(月) 18:16:46
>>1-17
1行に詰め込まないでインデントしようよ。
1行に詰め込まないでインデントしようよ。
2008/02/11(月) 18:58:15
最後の一つだけインデント入れてみた
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 srcTable = dataTable1.AsEnumerable() ;
var dstTable =
from row in srcTable
where row.Field<short>("LocationID") < 10
select row;
// ためしに表示
dataGridView1.DataSource = dataTable1;
dataGridView2.DataSource = dstTable.CopyToDataTable();
}
}
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 srcTable = dataTable1.AsEnumerable() ;
var dstTable =
from row in srcTable
where row.Field<short>("LocationID") < 10
select row;
// ためしに表示
dataGridView1.DataSource = dataTable1;
dataGridView2.DataSource = dstTable.CopyToDataTable();
}
}
2008/02/11(月) 19:11:14
どんどんコードが短くなる気持のよいビデオです
http://www.microsoft.com/uk/msdn/nuggets/nugget/227/Decomposing-LINQ.aspx
http://www.microsoft.com/uk/msdn/nuggets/nugget/227/Decomposing-LINQ.aspx
2008/02/12(火) 16:11:50
続き(>>17)
今日は System.Data.Linq.DataContext を使ったさらなる単純な例。
データベースへのアクセスの高速化もやりたいと思ったんですが、そんなの興味無い人多いと思うので、思いとどまって簡単化の方のみとします。
まずテーブルと同じ形式を持つクラスを作成します。
中身の無い { get; set; } は、event に対するdelegateのように、自動的にその型のインスタンスを生成してアクセスできるようにする物です。
C#の言語仕様書を見てください。
今日は System.Data.Linq.DataContext を使ったさらなる単純な例。
データベースへのアクセスの高速化もやりたいと思ったんですが、そんなの興味無い人多いと思うので、思いとどまって簡単化の方のみとします。
まずテーブルと同じ形式を持つクラスを作成します。
中身の無い { get; set; } は、event に対するdelegateのように、自動的にその型のインスタンスを生成してアクセスできるようにする物です。
C#の言語仕様書を見てください。
2008/02/12(火) 16:12:29
続き(>>23)
// Name の後ろにはテーブルの名前
[System.Data.Linq.Mapping.Table(Name = "Production.Location")]
public class TableLocation
{
// 重要:項目名はデータベースのコラム名とあわせておく
// ここでは、さらにプライマリキーとして認識させる
[System.Data.Linq.Mapping.Column(IsPrimaryKey = true)]
public short LocationID { get; set; }
[System.Data.Linq.Mapping.Column]
public string Name { get; set; }
[System.Data.Linq.Mapping.Column]
public System.Decimal CostRate { get; set; }
[System.Data.Linq.Mapping.Column]
public System.Decimal Availability { get; set; }
[System.Data.Linq.Mapping.Column]
public System.DateTime ModifiedDate { get; set; }
}
// Name の後ろにはテーブルの名前
[System.Data.Linq.Mapping.Table(Name = "Production.Location")]
public class TableLocation
{
// 重要:項目名はデータベースのコラム名とあわせておく
// ここでは、さらにプライマリキーとして認識させる
[System.Data.Linq.Mapping.Column(IsPrimaryKey = true)]
public short LocationID { get; set; }
[System.Data.Linq.Mapping.Column]
public string Name { get; set; }
[System.Data.Linq.Mapping.Column]
public System.Decimal CostRate { get; set; }
[System.Data.Linq.Mapping.Column]
public System.Decimal Availability { get; set; }
[System.Data.Linq.Mapping.Column]
public System.DateTime ModifiedDate { get; set; }
}
2008/02/12(火) 16:13:13
続き(>>24)
private void Test9()
{
// DataContext を使ったバージョン
using (var myDataContext = new System.Data.Linq.DataContext("Data Source=貴方のPC;Initial Catalog=AdventureWorks;Integrated Security=True"))
{
// サンプルデータベースからデータを取り込む
System.Data.Linq.Table<TableLocation> orginalTable = myDataContext.GetTable<TableLocation>();
// LocationIDが10以下の行のみのテーブルを作る
var lessThan10Table = from row in orginalTable where row.LocationID < 10 select row;
// ためしに表示
this.dataGridView1.DataSource = orginalTable;
this.dataGridView2.DataSource = lessThan10Table;
// *** 重要な特徴の紹介 ***
// キャストしなくても使えるのでミスが少なく便利である
foreach (TableLocation tmp in lessThan10Table)
{
System.Console.WriteLine("{0},{1},{2},{3},{4}"
, tmp.LocationID
, tmp.Name
, tmp.CostRate
, tmp.Availability
, tmp.ModifiedDate);
}
}
}
private void Test9()
{
// DataContext を使ったバージョン
using (var myDataContext = new System.Data.Linq.DataContext("Data Source=貴方のPC;Initial Catalog=AdventureWorks;Integrated Security=True"))
{
// サンプルデータベースからデータを取り込む
System.Data.Linq.Table<TableLocation> orginalTable = myDataContext.GetTable<TableLocation>();
// LocationIDが10以下の行のみのテーブルを作る
var lessThan10Table = from row in orginalTable where row.LocationID < 10 select row;
// ためしに表示
this.dataGridView1.DataSource = orginalTable;
this.dataGridView2.DataSource = lessThan10Table;
// *** 重要な特徴の紹介 ***
// キャストしなくても使えるのでミスが少なく便利である
foreach (TableLocation tmp in lessThan10Table)
{
System.Console.WriteLine("{0},{1},{2},{3},{4}"
, tmp.LocationID
, tmp.Name
, tmp.CostRate
, tmp.Availability
, tmp.ModifiedDate);
}
}
}
26デフォルトの名無しさん
2008/02/12(火) 16:14:20 今日はこれでおしまい
データベースを知らない人にも解りやすい、データベース不使用例もそのうち作ってみます。
データベースを知らない人にも解りやすい、データベース不使用例もそのうち作ってみます。
2008/02/12(火) 21:46:14
「プロジェクト」の「新しい項目の追加」で「LINQ to SQL クラス」のテンプレートが
追加されるけど知らない人多いよね。これで>>24のを自動生成してくれる。
追加されるけど知らない人多いよね。これで>>24のを自動生成してくれる。
28デフォルトの名無しさん
2008/02/13(水) 13:39:40 ども、>>1です、まだ始めたばかりで右も左もわかりませんがよろしくお願いします。
驚きました、プロジェクトから Linq To Sql を作成して、サーバーエクスプローラで必要なデータベースを接続したら、テーブルをドラックアンドドロップでポイだったんですね。
ちょっちょっと、これは何にもする事が無いです、いきなりこのスレ終了ですかぁ(^^;
せっかく建てたのだから何かネタ考えて続けて見ます・・・
private void Test10()
{
using (var dataContext = new TestTableDataContext())
{
var table = dataContext.GetTable<Location>();
this.dataGridView1.DataSource = table;
this.dataGridView2.DataSource = from row in table where row.LocationID < 10 select row;
}
}
驚きました、プロジェクトから Linq To Sql を作成して、サーバーエクスプローラで必要なデータベースを接続したら、テーブルをドラックアンドドロップでポイだったんですね。
ちょっちょっと、これは何にもする事が無いです、いきなりこのスレ終了ですかぁ(^^;
せっかく建てたのだから何かネタ考えて続けて見ます・・・
private void Test10()
{
using (var dataContext = new TestTableDataContext())
{
var table = dataContext.GetTable<Location>();
this.dataGridView1.DataSource = table;
this.dataGridView2.DataSource = from row in table where row.LocationID < 10 select row;
}
}
2008/02/13(水) 13:49:37
このデザイナは、細かい所まで完全に実装してくれますね
自前で動的にテーブルやDBを作成するにしても、一旦SqlSever上でダミーテーブルを作って
コードを生成しておいて、それをコピペで取ってきて変更する方が効率が良いように思えてきました。
自前で動的にテーブルやDBを作成するにしても、一旦SqlSever上でダミーテーブルを作って
コードを生成しておいて、それをコピペで取ってきて変更する方が効率が良いように思えてきました。
2008/02/13(水) 14:02:30
2008/02/13(水) 14:09:09
DB板は、あっちはアドミニの人ばかりです。
マの人がほとんど居ないから余計伸びないです。
プログラム的な事は聞いても答えが返ってくることまずないですし。
マの人がほとんど居ないから余計伸びないです。
プログラム的な事は聞いても答えが返ってくることまずないですし。
2008/02/15(金) 00:07:33
検索してからC#オブジェクトに変換する手間がとても万度くさい自分はLINQヽ(´ー`)ノマンセーです。
遅くても(・ε・)キニシナイ!!。
遅くても(・ε・)キニシナイ!!。
33デフォルトの名無しさん
2008/02/15(金) 03:30:14 IronLisp#早く作れよ
2008/02/15(金) 08:59:25
ググれカス
2008/02/15(金) 10:20:31
DBを使わなくてもLINQは便利なんだよ〜!ってことを布教するためw、
普通のコレクションに対してロジックを実行するクエリのサンプルを示してみます。
>>10が言うように、グループ化の処理をクエリ一発で書けるのは実に魅力的です。
ファイル名を格納したstring配列 files に対して処理を行います。
// 拡張子ごとにファイル名をグループ化するクエリ
var extGroupQuery = from filename in files
let ext = System.IO.Path.GetExtension(filename).ToLower()
group filename by ext into extGroup
select extGroup;
// グループ化したクエリは2重のIEnumerable<T>になってます
foreach (var extGroup in extGroupQuery)
{
Console.WriteLine("Extension: {0}, Count: {1}", extGroup.Key, extGroup.Count());
foreach (var filename in extGroup)
{
Console.WriteLine("\t{0}", filename);
}
}
普通のコレクションに対してロジックを実行するクエリのサンプルを示してみます。
>>10が言うように、グループ化の処理をクエリ一発で書けるのは実に魅力的です。
ファイル名を格納したstring配列 files に対して処理を行います。
// 拡張子ごとにファイル名をグループ化するクエリ
var extGroupQuery = from filename in files
let ext = System.IO.Path.GetExtension(filename).ToLower()
group filename by ext into extGroup
select extGroup;
// グループ化したクエリは2重のIEnumerable<T>になってます
foreach (var extGroup in extGroupQuery)
{
Console.WriteLine("Extension: {0}, Count: {1}", extGroup.Key, extGroup.Count());
foreach (var filename in extGroup)
{
Console.WriteLine("\t{0}", filename);
}
}
3635
2008/02/15(金) 10:24:47 さらに集計処理を行います
クエリの中でオブジェクトを生成し、集計処理に利用したりできます
// 拡張子ごとの合計サイズを取得する(foreachを使うとこんな感じ)
Dictionary<string, long> sizeDic = new Dictionary<string, long>();
foreach (var extGroup in extGroupQuery)
{
var sizeQuery1 = from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length;
long totalSize = sizeQuery1.Sum();
sizeDic[extGroup.Key] = totalSize;
}
// 拡張子ごとの合計サイズを取得する(サブクエリを使う)
// クエリ内でさらにクエリを定義できます(totalSizeQueryはsizeQuery1とまったく同じです)
var sizeQuery2 = from extGroup in extGroupQuery
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery.Sum() };
クエリの中でオブジェクトを生成し、集計処理に利用したりできます
// 拡張子ごとの合計サイズを取得する(foreachを使うとこんな感じ)
Dictionary<string, long> sizeDic = new Dictionary<string, long>();
foreach (var extGroup in extGroupQuery)
{
var sizeQuery1 = from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length;
long totalSize = sizeQuery1.Sum();
sizeDic[extGroup.Key] = totalSize;
}
// 拡張子ごとの合計サイズを取得する(サブクエリを使う)
// クエリ内でさらにクエリを定義できます(totalSizeQueryはsizeQuery1とまったく同じです)
var sizeQuery2 = from extGroup in extGroupQuery
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery.Sum() };
3735
2008/02/15(金) 10:26:11 // .Sum()の場所を変えてみる(結果はsizeQuery2と同じです)
var sizeQuery3 = from extGroup in extGroupQuery
let totalSize = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// サブクエリを拡張メソッドに変えてみる(場合によってはサブクエリよりもすっきり書けます)
var sizeQuery4 = from extGroup in extGroupQuery
let totalSize = extGroup.Select<string, long>(filename => new System.IO.FileInfo(filename).Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// extGroupQuery, sizeQuery2をまとめてみる
var sizeQuery5 = from filename in files
let ext = System.IO.Path.GetExtension(filename).ToLower()
group filename by ext into extGroup
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery };
とりあえず以上です。
もっと気の利いた例を作ったら、また書き込みます。
var sizeQuery3 = from extGroup in extGroupQuery
let totalSize = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// サブクエリを拡張メソッドに変えてみる(場合によってはサブクエリよりもすっきり書けます)
var sizeQuery4 = from extGroup in extGroupQuery
let totalSize = extGroup.Select<string, long>(filename => new System.IO.FileInfo(filename).Length).Sum()
select new { Extension = extGroup.Key, TotalSize = totalSize };
// extGroupQuery, sizeQuery2をまとめてみる
var sizeQuery5 = from filename in files
let ext = System.IO.Path.GetExtension(filename).ToLower()
group filename by ext into extGroup
let totalSizeQuery = (from filename in extGroup
let fileinfo = new System.IO.FileInfo(filename)
select fileinfo.Length)
select new { Extension = extGroup.Key, TotalSize = totalSizeQuery };
とりあえず以上です。
もっと気の利いた例を作ったら、また書き込みます。
3835
2008/02/15(金) 11:52:15 >>35-37の応用で、ファイルの重複を検出するコードをLINQでコンパクトに書いてみます。
次のメソッドが存在するという前提です。
static string GetMD5String(string filename)
{
using (System.Security.Cryptography.MD5CryptoServiceProvider md5
= new System.Security.Cryptography.MD5CryptoServiceProvider())
{
byte[] data = System.IO.File.ReadAllBytes(filename);
byte[] hash = md5.ComputeHash(data);
StringBuilder buf = new StringBuilder();
foreach (byte b in hash)
{
buf.AppendFormat("{0:x2}", b);
}
return buf.ToString();
}
}
次のメソッドが存在するという前提です。
static string GetMD5String(string filename)
{
using (System.Security.Cryptography.MD5CryptoServiceProvider md5
= new System.Security.Cryptography.MD5CryptoServiceProvider())
{
byte[] data = System.IO.File.ReadAllBytes(filename);
byte[] hash = md5.ComputeHash(data);
StringBuilder buf = new StringBuilder();
foreach (byte b in hash)
{
buf.AppendFormat("{0:x2}", b);
}
return buf.ToString();
}
}
3935
2008/02/15(金) 11:52:51 まずは単純だけど遅いバージョンから
// ファイルをハッシュ値でグループ化する
// 全ファイルを読み込んでハッシュ値を計算するので遅いです
var hashGroupQuery = from filehash in
(from filename in files
let hash = GetMD5String(filename)
select new { Filename = filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery)
{
Console.WriteLine("Hash: {0}, Count: {1}", hashGroup.Key, hashGroup.Count());
foreach (var filehash in hashGroup)
{
Console.WriteLine("\t{0}", filehash.Filename);
}
}
// ファイルをハッシュ値でグループ化する
// 全ファイルを読み込んでハッシュ値を計算するので遅いです
var hashGroupQuery = from filehash in
(from filename in files
let hash = GetMD5String(filename)
select new { Filename = filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery)
{
Console.WriteLine("Hash: {0}, Count: {1}", hashGroup.Key, hashGroup.Count());
foreach (var filehash in hashGroup)
{
Console.WriteLine("\t{0}", filehash.Filename);
}
}
4035
2008/02/15(金) 11:56:08 次に前処理を行って高速化したバージョン
// 処理を高速化するため、ファイルサイズでグループ化しておく
// (ファイルサイズはファイルを読み込まなくても取得できるので)
var sizeGroupQuery = from filesize in
(from filename in files
let fileinfo = new System.IO.FileInfo(filename)
let size = fileinfo.Length
select new { Filename = filename, Size = size })
group filesize by filesize.Size into sizeGroup
where sizeGroup.Count() >= 2
select sizeGroup;
foreach (var sizeGroup in sizeGroupQuery)
{
// ハッシュ値でグループ化する
var hashGroupQuery2 = from filehash in
(from filesize in sizeGroup
let hash = GetMD5String(filesize.Filename)
select new { Filename = filesize.Filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery2)
{
// (行数オーバーのため略 >>39と同じです)
}
}
// 処理を高速化するため、ファイルサイズでグループ化しておく
// (ファイルサイズはファイルを読み込まなくても取得できるので)
var sizeGroupQuery = from filesize in
(from filename in files
let fileinfo = new System.IO.FileInfo(filename)
let size = fileinfo.Length
select new { Filename = filename, Size = size })
group filesize by filesize.Size into sizeGroup
where sizeGroup.Count() >= 2
select sizeGroup;
foreach (var sizeGroup in sizeGroupQuery)
{
// ハッシュ値でグループ化する
var hashGroupQuery2 = from filehash in
(from filesize in sizeGroup
let hash = GetMD5String(filesize.Filename)
select new { Filename = filesize.Filename, Hash = hash })
group filehash by filehash.Hash into hashGroup
where hashGroup.Count() >= 2
select hashGroup;
foreach (var hashGroup in hashGroupQuery2)
{
// (行数オーバーのため略 >>39と同じです)
}
}
41デフォルトの名無しさん
2008/02/16(土) 00:03:522008/02/16(土) 00:04:35
Q.データを確認したい
ツールバーにある DataGridView は、とりあえずデータの中身を見てみたい時にとても便利です。
DataSource プロパティーにデータをセットする事で見ることができます。
ただし、ここに設定できるオブジェクトは IList , IListSource , IBindingList , IBindingListView
の四つです。
また、要素は、フィールドメンバでは駄目で、プロパティーでなければなりません。
C# 3.0 より追加された省略形が便利です。
class Row {
public int Data1 { set ; get ; }
public int Data2 { set ; get ; }
}
dataGridView1.DataSource = new Row[] { new Row() { Data1 = 1, Data2 = 2 } };
ツールバーにある DataGridView は、とりあえずデータの中身を見てみたい時にとても便利です。
DataSource プロパティーにデータをセットする事で見ることができます。
ただし、ここに設定できるオブジェクトは IList , IListSource , IBindingList , IBindingListView
の四つです。
また、要素は、フィールドメンバでは駄目で、プロパティーでなければなりません。
C# 3.0 より追加された省略形が便利です。
class Row {
public int Data1 { set ; get ; }
public int Data2 { set ; get ; }
}
dataGridView1.DataSource = new Row[] { new Row() { Data1 = 1, Data2 = 2 } };
2008/02/16(土) 00:05:16
Q.from ... として作ったデータが見れない
IList 等に変換してしまうのが便利です。
var tableX = new [] {
new { X=1 , P=0.25 },
new { X=2 , P=0.50 },
new { X=3 , P=0.25 },
};
var table2 = from row in tableX orderby row.P select row;
dataGridView1.DataSource = table2.ToArray();
IList 等に変換してしまうのが便利です。
var tableX = new [] {
new { X=1 , P=0.25 },
new { X=2 , P=0.50 },
new { X=3 , P=0.25 },
};
var table2 = from row in tableX orderby row.P select row;
dataGridView1.DataSource = table2.ToArray();
2008/02/16(土) 00:05:53
Q.表の中から必要な要素を選択したい
where句を使います。
class Row {
public int X { set ; get ; }
public double P { set ; get ; }
}
var tableX = new Row[] {
new Row() { X=1 , P=0.25 },
new Row() { X=2 , P=0.50 },
new Row() { X=3 , P=0.25 },
};
// Xが2以下の行を選択する
var table1 = from row in tableX where row.X <= 2 select row;
// Xが2以下の行を選択したのち、さらに P <= 0.25 となる行を絞り込む
var table2 = from row in tableX where row.X <= 2 where row.P <= 0.25 select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
where句を使います。
class Row {
public int X { set ; get ; }
public double P { set ; get ; }
}
var tableX = new Row[] {
new Row() { X=1 , P=0.25 },
new Row() { X=2 , P=0.50 },
new Row() { X=3 , P=0.25 },
};
// Xが2以下の行を選択する
var table1 = from row in tableX where row.X <= 2 select row;
// Xが2以下の行を選択したのち、さらに P <= 0.25 となる行を絞り込む
var table2 = from row in tableX where row.X <= 2 where row.P <= 0.25 select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
2008/02/16(土) 00:06:24
Q.表をソートしたい
1.orderby句を使います、単純なソートは以下の通りです。
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { D=3 },
new Row() { D=1 },
new Row() { D=4 },
new Row() { D=1 },
new Row() { D=5 },
new Row() { D=9 },
};
// 昇順(ascending省略可)
var table1 = from row in tableOrg orderby row.D ascending select row;
// 降順
var table2 = from row in tableOrg orderby row.D descending select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
1.orderby句を使います、単純なソートは以下の通りです。
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { D=3 },
new Row() { D=1 },
new Row() { D=4 },
new Row() { D=1 },
new Row() { D=5 },
new Row() { D=9 },
};
// 昇順(ascending省略可)
var table1 = from row in tableOrg orderby row.D ascending select row;
// 降順
var table2 = from row in tableOrg orderby row.D descending select row;
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
2008/02/16(土) 00:15:04
2.二つ以上の項目についてソートする場合は以下の通りです。
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S, row.D select row;
dataGridView1.DataSource = table1.ToArray();
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S, row.D select row;
dataGridView1.DataSource = table1.ToArray();
2008/02/16(土) 00:15:29
3.二回に分けてソートする場合は以下の通りです。(2と結果が異なります)
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S orderby row.D select row;
dataGridView1.DataSource = table1.ToArray();
class Row {
public string S { set; get; }
public int D { set; get; }
}
var tableOrg = new Row[] {
new Row() { S="A" , D=3 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=4 },
new Row() { S="B" , D=1 },
new Row() { S="A" , D=5 },
new Row() { S="B" , D=9 },
};
// SとD を使って比較します
var table1 = from row in tableOrg orderby row.S orderby row.D select row;
dataGridView1.DataSource = table1.ToArray();
2008/02/16(土) 09:02:20
ところで、LINQってどう発音するの?
2008/02/16(土) 09:48:38
発音は link と同じらしいよ。
2008/02/16(土) 17:51:35
>>1 です、今日は、表の結合のやり方を紹介します。
2008/02/16(土) 17:52:36
Q.表を結合したい1(クロス結合)
Row1の表にRow2の表の要素をすべて結合します。
class Row1 { public string S { set; get; } }
class Row2 { public string S { set; get; } }
class Row3 { public string R1 { set; get; } public string R2 { set; get; } }
var tableOrg1 = new Row1[] { new Row1() { S="赤" }, new Row1() { S="青" },};
var tableOrg2 = new Row2[] { new Row2() { S="青" }, new Row2() { S="緑" },};
var table1 = from row1 in tableOrg1 from row2 in tableOrg2 select new Row3() { R1 = row1.S, R2 = row2.S };
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
table1 の結果
赤 青
赤 緑
青 青
青 緑
この機能、一見は使い道がなさそうですが、これをフィルターしてゆく事により価値が出てきます。
Row1の表にRow2の表の要素をすべて結合します。
class Row1 { public string S { set; get; } }
class Row2 { public string S { set; get; } }
class Row3 { public string R1 { set; get; } public string R2 { set; get; } }
var tableOrg1 = new Row1[] { new Row1() { S="赤" }, new Row1() { S="青" },};
var tableOrg2 = new Row2[] { new Row2() { S="青" }, new Row2() { S="緑" },};
var table1 = from row1 in tableOrg1 from row2 in tableOrg2 select new Row3() { R1 = row1.S, R2 = row2.S };
dataGridView1.DataSource = table1.ToArray();
dataGridView2.DataSource = table2.ToArray();
table1 の結果
赤 青
赤 緑
青 青
青 緑
この機能、一見は使い道がなさそうですが、これをフィルターしてゆく事により価値が出てきます。
2008/02/16(土) 17:53:19
Q.表を結合したい2(等価結合、きっと良く使うに違いない)
Row1の表にRow2の表の要素を普通に結合します。
この例では、 tableOrg1 の Index 番号と同じ Index のある tableOrg2 の列に結合します。
class Row1 { public int LineNo { set; get; } public int Index { set; get; } }
class Row2 { public int Index { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
class Row3 { public int LineNo { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
var tableOrg1 = new Row1[] {
new Row1() { LineNo=1 , Index = 3 },
new Row1() { LineNo=2 , Index = 1 },
new Row1() { LineNo=3 , Index = 4 },
new Row1() { LineNo=4 , Index = 1 },
new Row1() { LineNo=5 , Index = 5 },
};
var tableOrg2 = new Row2[] {
new Row2() { Index=1 , Data1 = "Index1" , Data2="ABC" },
new Row2() { Index=2 , Data1 = "Index2" , Data2="DEF" },
new Row2() { Index=3 , Data1 = "Index3" , Data2="GHI" },
new Row2() { Index=4 , Data1 = "Index4" , Data2="JKL" },
new Row2() { Index=5 , Data1 = "Index5" , Data2="MNL" },
};
var table1 = from row1 in tableOrg1 join row2 in tableOrg2 on row1.Index equals row2.Index select new Row3() { LineNo = row1.LineNo, Data1 = row2.Data1, Data2 = row2.Data2 };
table1 の結果
1 Index3 GHI
2 Index1 ABC
3 Index4 JKL
4 Index1 ABC
5 Index5 MNL
Row1の表にRow2の表の要素を普通に結合します。
この例では、 tableOrg1 の Index 番号と同じ Index のある tableOrg2 の列に結合します。
class Row1 { public int LineNo { set; get; } public int Index { set; get; } }
class Row2 { public int Index { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
class Row3 { public int LineNo { set; get; } public string Data1 { set; get; } public string Data2 { set; get; } }
var tableOrg1 = new Row1[] {
new Row1() { LineNo=1 , Index = 3 },
new Row1() { LineNo=2 , Index = 1 },
new Row1() { LineNo=3 , Index = 4 },
new Row1() { LineNo=4 , Index = 1 },
new Row1() { LineNo=5 , Index = 5 },
};
var tableOrg2 = new Row2[] {
new Row2() { Index=1 , Data1 = "Index1" , Data2="ABC" },
new Row2() { Index=2 , Data1 = "Index2" , Data2="DEF" },
new Row2() { Index=3 , Data1 = "Index3" , Data2="GHI" },
new Row2() { Index=4 , Data1 = "Index4" , Data2="JKL" },
new Row2() { Index=5 , Data1 = "Index5" , Data2="MNL" },
};
var table1 = from row1 in tableOrg1 join row2 in tableOrg2 on row1.Index equals row2.Index select new Row3() { LineNo = row1.LineNo, Data1 = row2.Data1, Data2 = row2.Data2 };
table1 の結果
1 Index3 GHI
2 Index1 ABC
3 Index4 JKL
4 Index1 ABC
5 Index5 MNL
2008/02/16(土) 17:54:00
Q.表を結合したい3(非等価結合、やや使う違いない)
let を使って、選択した行を保持する事により実現できます。
class 得点表 { public string 氏名 { set; get; } public int 得点 { set; get; } }
class 評価表 { public int 以上 { set; get; } public int 未満 { set; get; } public string 評価 { set; get; } }
class 氏名と評価 { public string 氏名 { set; get; } public string 評価 { set; get; } }
var tableOrg1 = new 得点表[] {
new 得点表() { 氏名="Aさん" , 得点=10 },
new 得点表() { 氏名="Bさん" , 得点=100 },
new 得点表() { 氏名="Cさん" , 得点=60 },
};
var tableOrg2 = new 評価表[] {
new 評価表() { 以上=0 , 未満=20, 評価="丙" },
new 評価表() { 以上=20 , 未満=70, 評価="乙" },
new 評価表() { 以上=70 , 未満=101, 評価="甲" },
};
var table1 = from row1 in tableOrg1
let selectLines = from row2 in tableOrg2 where (row2.以上 <= row1.得点 && row1.得点 < row2.未満) select row2
select new 氏名と評価() { 氏名 = row1.氏名, 評価 = selectLines.First().評価 };
table1 の結果
Aさん 丙
Bさん 甲
Cさん 乙
あんま綺麗じゃない……equalsに対してLINQの拡張求む > Microsoft
let を使って、選択した行を保持する事により実現できます。
class 得点表 { public string 氏名 { set; get; } public int 得点 { set; get; } }
class 評価表 { public int 以上 { set; get; } public int 未満 { set; get; } public string 評価 { set; get; } }
class 氏名と評価 { public string 氏名 { set; get; } public string 評価 { set; get; } }
var tableOrg1 = new 得点表[] {
new 得点表() { 氏名="Aさん" , 得点=10 },
new 得点表() { 氏名="Bさん" , 得点=100 },
new 得点表() { 氏名="Cさん" , 得点=60 },
};
var tableOrg2 = new 評価表[] {
new 評価表() { 以上=0 , 未満=20, 評価="丙" },
new 評価表() { 以上=20 , 未満=70, 評価="乙" },
new 評価表() { 以上=70 , 未満=101, 評価="甲" },
};
var table1 = from row1 in tableOrg1
let selectLines = from row2 in tableOrg2 where (row2.以上 <= row1.得点 && row1.得点 < row2.未満) select row2
select new 氏名と評価() { 氏名 = row1.氏名, 評価 = selectLines.First().評価 };
table1 の結果
Aさん 丙
Bさん 甲
Cさん 乙
あんま綺麗じゃない……equalsに対してLINQの拡張求む > Microsoft
54デフォルトの名無しさん
2008/02/16(土) 17:54:50 そのうち、逆引きLINQでも作って、纏めてみたいな……
こうやって、Q&A を作ってみると、LINQは集合の積的な演算は強いのに和の方は至って貧弱なんですね。
全部LINQにしなくても適当にメソッドを使えば良いという話もありますが……
こうやって、Q&A を作ってみると、LINQは集合の積的な演算は強いのに和の方は至って貧弱なんですね。
全部LINQにしなくても適当にメソッドを使えば良いという話もありますが……
2008/02/16(土) 18:39:49
>>54
まあ、リレーショナルデータベースがそういうものだからね<テーブル積を多用
まあ、リレーショナルデータベースがそういうものだからね<テーブル積を多用
2008/02/16(土) 18:59:05
2008/02/16(土) 19:11:27
そういう概念を導入すると、
作り手だけでなくて、使い手にも圏論の知識を強要することにならないかな。
LINQ は、リレーショナルデータベースの文化を
OOP 言語に導入したものだから、
少なくとも SQL チックに select とか where ってキーワードを使ってる限り、
リレーショナルデータベースの文化を大きく逸脱するようなことは
しない方がいいと思う。
ヘジたんがクエリ式否定派(関数形式ばっかり使う)な理由も
そういうところにあるのかもね。
作り手だけでなくて、使い手にも圏論の知識を強要することにならないかな。
LINQ は、リレーショナルデータベースの文化を
OOP 言語に導入したものだから、
少なくとも SQL チックに select とか where ってキーワードを使ってる限り、
リレーショナルデータベースの文化を大きく逸脱するようなことは
しない方がいいと思う。
ヘジたんがクエリ式否定派(関数形式ばっかり使う)な理由も
そういうところにあるのかもね。
2008/02/16(土) 19:11:51
>>53
ちょっとだけ短くしたよ。
var table1 = from row1 in tableOrg1
let 評価 = tableOrg2.First(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
select new { row1.氏名, 評価.評価 };
ちょっとだけ短くしたよ。
var table1 = from row1 in tableOrg1
let 評価 = tableOrg2.First(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
select new { row1.氏名, 評価.評価 };
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- なぜリベラルは人気がないのか 斎藤幸平さんが指し示す未来への道筋:朝日新聞 [少考さん★]
- 【日本人の旅行離れ】国内旅行すら行けなくなった……オーバーツーリズムだけじゃない 旅行者減少の異常事態 ★2 [ぐれ★]
- “ひとり焼肉”でおなじみ「焼肉ライク」が閉店ラッシュ。なぜ「コスパが悪い」と言われてしまうのか [Gecko★]
- 女性天皇「賛成」69%、将来の皇位継承「不安」68%…読売世論調査 [蚤の市★]
- なぜ安っぽく見えてしまうのか…? ダウンジャケット姿が垢抜けない人の"意外な盲点" (ビジネスマンのためのスタイリスト) [少考さん★]
- 【日中】経団連会長、1月の北京訪問に暗雲 中国は受け入れ是非明らかにせず 関係「政冷経冷」に [煮卵★]
- 「SCORE」←これなんて読むんや?🙋🏡
- 【高市朗報】鈴木大臣「嫌儲のデマに騙されないで。お米券の使い勝手は悪くない。卵味噌醤油も買えます。現金と変わりません」 [517459952]
- iPhone高騰する説、デマだった!ハードからOSまで全てAppleが作るからメモリも自給自足、iOSはメモリ少なくて良いから128MBぐらいでOK [749674962]
- 🏡おい!返事しろ︎︎!知的障害者!
- 【悲報】ワンピースの尾田栄一郎の描く女が気持ち悪過ぎると大炎上中wwwwwwwwwwwwwwwwwwww [802034645]
- 【悲報】東京40代「生活苦しい!戸建てなんて絶対無理…」地方20代「家と車買って子供できた~今日は家族でモールで買い物」 [732289945]
