【VB.NET】LINQ友の会【C#, C♯, C#】at TECH
【VB.NET】LINQ友の会【C#, C♯, C#】 - 暇つぶし2ch2:デフォルトの名無しさん
08/02/09 23:52:34
>>1 もこれから使い始めます、答えられそうな質問にはどんどん答えます、無理なのは……誰かお願い。


3:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/02/10 00:20:06
部分的にSQLがかけますよ、って感じか
どーなんだろ、便利か?これ


5:デフォルトの名無しさん
08/02/10 00:25:18
まあ、便利なんだろうけど、あまり優秀でないプログラマに使わせるとこんな記述が
そこらじゅうにばら撒かれたきわめて保守し辛いプログラムが量産されるような気が
する。

6:デフォルトの名無しさん
08/02/10 00:34:33
もう全部の言語合体したのを作っちゃいなよw

CLR自体に新しい何かが加わったの?
.NET層のインターフェイス?
シンタックスシュガーにも見えなくもない。
全然c#に触れてないので見当違いなこと言ってたらごめんよ。

7:デフォルトの名無しさん
08/02/10 00:53:14
>>6
ラムダ式のシンタックスシュガーですよ、かなりなんでも出来ます。

8:デフォルトの名無しさん
08/02/10 00:55:57
明日は、とりあえず難しい事考えなくても、簡単に使えるサンプルでも考えてみるかな・・・

9:デフォルトの名無しさん
08/02/10 01:15:38
洋書だとC#3の本がかなり出てるらしいけど、日本語のはぜんぜんでないな。

10:デフォルトの名無しさん
08/02/10 07:20:46
何が便利かって、グループ化の機能が便利だ。

11:762
08/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:デフォルトの名無しさん
08/02/11 15:15:26
データベースからデータを拾ってきて、LocationID が 10 未満の行を取り出すサンプル。
従来コードから徐々に LINQ に書き換えて行って見ました。
データは、Microsoft SQL Server 2005 に最初から入っているものです。
こちらの使用環境は Professional エデッションで、二枚付いているディスクはフルインストール
ウインドウズ認証でインストールして特に変わった設定がしてなければ、"貴方のPC" を自分のPC名に書き換えれば動くと思います、多分。
データベースは、最初から入っているサンプルデータ AdventureWorks の中の Location(Production) を使ってみました。
DataGridView コントロールを二つ貼り付けて、ボタンを一つ用意して、ボタンプッシュのイベントで実行しています。


13:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/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;
}
}


18:デフォルトの名無しさん
08/02/11 15:28:13
さて、次はLINQ to Sql にいくか、それともしょうもない内容にすべか
誰も来なければそろそろ諦めるかw

19:デフォルトの名無しさん
08/02/11 17:33:56
LINQ: .NET 統合言語クエリ
URLリンク(www.microsoft.com)

Part4 LINQで変わるデータベース開発:ITpro
URLリンク(itpro.nikkeibp.co.jp)


スレ立てるの早すぎだと思われ
然程使ってもいないのに意見の交換なんて出来ませぬ

20:デフォルトの名無しさん
08/02/11 18:16:46
>>1-17
1行に詰め込まないでインデントしようよ。

21:デフォルトの名無しさん
08/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();
 }
}

22:デフォルトの名無しさん
08/02/11 19:11:14
どんどんコードが短くなる気持のよいビデオです
URLリンク(www.microsoft.com)

23:デフォルトの名無しさん
08/02/12 16:11:50
続き(>>17)
今日は System.Data.Linq.DataContext を使ったさらなる単純な例。
データベースへのアクセスの高速化もやりたいと思ったんですが、そんなの興味無い人多いと思うので、思いとどまって簡単化の方のみとします。
まずテーブルと同じ形式を持つクラスを作成します。
中身の無い { get; set; } は、event に対するdelegateのように、自動的にその型のインスタンスを生成してアクセスできるようにする物です。
C#の言語仕様書を見てください。


24:デフォルトの名無しさん
08/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; }
}


25:デフォルトの名無しさん
08/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);
}
}
}


26:デフォルトの名無しさん
08/02/12 16:14:20
今日はこれでおしまい
データベースを知らない人にも解りやすい、データベース不使用例もそのうち作ってみます。


27:デフォルトの名無しさん
08/02/12 21:46:14
「プロジェクト」の「新しい項目の追加」で「LINQ to SQL クラス」のテンプレートが
追加されるけど知らない人多いよね。これで>>24のを自動生成してくれる。

28:デフォルトの名無しさん
08/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;
}
}

29:デフォルトの名無しさん
08/02/13 13:49:37
このデザイナは、細かい所まで完全に実装してくれますね
自前で動的にテーブルやDBを作成するにしても、一旦SqlSever上でダミーテーブルを作って
コードを生成しておいて、それをコピペで取ってきて変更する方が効率が良いように思えてきました。

30:デフォルトの名無しさん
08/02/13 14:02:30
DB板のもあんまり延びてないね
スレリンク(db板)l50


31:デフォルトの名無しさん
08/02/13 14:09:09
DB板は、あっちはアドミニの人ばかりです。
マの人がほとんど居ないから余計伸びないです。
プログラム的な事は聞いても答えが返ってくることまずないですし。

32:デフォルトの名無しさん
08/02/15 00:07:33
検索してからC#オブジェクトに変換する手間がとても万度くさい自分はLINQヽ(´ー`)ノマンセーです。
遅くても(・ε・)キニシナイ!!。

33:デフォルトの名無しさん
08/02/15 03:30:14
IronLisp#早く作れよ

34:デフォルトの名無しさん
08/02/15 08:59:25
ググれカス

35:デフォルトの名無しさん
08/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);
  }
}


36:35
08/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() };


37:35
08/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 };

とりあえず以上です。
もっと気の利いた例を作ったら、また書き込みます。

38:35
08/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();
  }
}

39:35
08/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);
  }
}

40:35
08/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と同じです)
  }
}

41:デフォルトの名無しさん
08/02/16 00:03:52
>>35
おお >>1 です、いらっしゃいまし、どんどん布教してあげてください。
let とか小技聞いていて面白いですね。
私の方は、まだ初めて一週間と初心者なので、もっと基本的でつまらない物やっていきます。

今日は、下手をすれば、C#さえ初心者の人向けのQ&Aを作ってみようと思います。
結果の簡単な確認方法と、選択・ソートです。
明日以後、表の結合等をやってみます、そのあとは、ググればありそうなのに無いLINQの文法の詳細解説あたりをやってみます。

42:デフォルトの名無しさん
08/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 } };


43:デフォルトの名無しさん
08/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();


44:デフォルトの名無しさん
08/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();


45:デフォルトの名無しさん
08/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();


46:デフォルトの名無しさん
08/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();


47:デフォルトの名無しさん
08/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();


48:デフォルトの名無しさん
08/02/16 09:02:20
ところで、LINQってどう発音するの?

49:デフォルトの名無しさん
08/02/16 09:48:38
発音は link と同じらしいよ。

50:デフォルトの名無しさん
08/02/16 17:51:35
>>1 です、今日は、表の結合のやり方を紹介します。


51:デフォルトの名無しさん
08/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 の結果
 赤 青
 赤 緑
 青 青
 青 緑
この機能、一見は使い道がなさそうですが、これをフィルターしてゆく事により価値が出てきます。


52:デフォルトの名無しさん
08/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

53:デフォルトの名無しさん
08/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

54:デフォルトの名無しさん
08/02/16 17:54:50
そのうち、逆引きLINQでも作って、纏めてみたいな……
こうやって、Q&A を作ってみると、LINQは集合の積的な演算は強いのに和の方は至って貧弱なんですね。
全部LINQにしなくても適当にメソッドを使えば良いという話もありますが……

55:デフォルトの名無しさん
08/02/16 18:39:49
>>54
まあ、リレーショナルデータベースがそういうものだからね<テーブル積を多用

56:デフォルトの名無しさん
08/02/16 18:59:05
>>55
他にも同値分割とか余りとか(袋の中身を色で割ると、それぞれの色で分類された集合と、色なし集合になるといった概念です)、まだまだ綺麗にできる所があるなと >>1 は感じてます
マイクロソフトリサーチの人たちに、ぜひ圏論(この種の概念の理論がいっぱいあります)の研究をしてみてもらいたいなと……
そしてこの恐ろしげな概念を誰の手にも簡単に使える直感的で便利機能に仕上げて欲しいものです。

57:デフォルトの名無しさん
08/02/16 19:11:27
そういう概念を導入すると、
作り手だけでなくて、使い手にも圏論の知識を強要することにならないかな。

LINQ は、リレーショナルデータベースの文化を
OOP 言語に導入したものだから、
少なくとも SQL チックに select とか where ってキーワードを使ってる限り、
リレーショナルデータベースの文化を大きく逸脱するようなことは
しない方がいいと思う。

ヘジたんがクエリ式否定派(関数形式ばっかり使う)な理由も
そういうところにあるのかもね。

58:デフォルトの名無しさん
08/02/16 19:11:51
>>53
ちょっとだけ短くしたよ。

var table1 = from row1 in tableOrg1
        let 評価 = tableOrg2.First(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
        select new { row1.氏名, 評価.評価 };

59:デフォルトの名無しさん
08/02/16 19:15:04
あと、同値分類みたいなのは、group by じゃだめ?

60:58
08/02/16 19:24:17
>>53
パターンマッチっぽくしてみたよ。

var table1 =
from row1 in tableOrg1
let 評価結果 = tableOrg2.Where(row2 => row2.以上 <= row1.得点 && row1.得点 < row2.未満)
                .Select(row2 => row2.評価)
                .Concat(Enumerable.Repeat("見つからないよ", 1))
                .Take(1)
from 評価 in 評価結果
select new { row1.氏名, 評価 };

61:デフォルトの名無しさん
08/02/16 20:13:38
>>1です

>>57
概念を導入することと、どう表現してどう使わせるかは違うと思うんですよ
高度な概念も、図にしてみれば、あんたバカ、何当り前の事をと思わずにはいられない概念は多いと思うんですよ。
圏論のそんな物の内の一つだと思っています。
ちなみにヘジたん理論無視の直感実装大好きです、実装は理屈じゃないですよ、いいと思ったらそれがいいんだと思ってます。
理屈は後付け、原爆の爆縮レンズが開発される時に、火薬職人が二種類の火薬使えばいいじゃんといって、頭でっかちのノイマンが計算するっていうのは悪くないと
ここでは、火薬職人がヘジたんで、頭でっかちがリサーチの人たちですね。

>>60
ありがとさんです、なるほどなるほど、いろいろ参考になりますです。
まだまだ初心者なんで今後ともよろしくお願いします。

62:デフォルトの名無しさん
08/02/16 20:26:54
高度な概念といえば、たとえばλ式なんかがそうなんですが、関数だと思うと恐ろしい事になりますが、
あれってとどのつまりは、引数が添え字になっている唯のベクトルですよね。なにやら要素が並んでいるだけの物です。
よく無限次元になってしまうので、普通に書けないからああ書いたというだけで……
もっと解り易くならないかなと思ったりします。

63:デフォルトの名無しさん
08/02/16 21:07:54
DB屋もやってる俺からみると、これはぶっちゃけキモい
変にSQLの知識あるとちょっと慣れそうにないなぁ、これは

64:デフォルトの名無しさん
08/02/17 00:29:39
>>63
俺も一応オラクルマスター持ちなんだが(システム屋から足を洗って長いけど)、
それはそれ、これはこれだな。
DBとだけ使っている限りは、SQL以上のことができるわけじゃないから「ただのキモいSQL」という見方も、そう間違ってはいないだろう。
SQLを基準にして見れば、SQLとの違いが気持ち悪いのは確か。しかし、メモリ上のデータのグループ化やら結合やら、定型的なわりに再利用しづらいコードを
いちいち書いては「こんな処理、SQLならSELECT文一発なのに」と思っていた人にとっては、むしろSQLに近づいた感じなのではないだろうか。

65:デフォルトの名無しさん
08/02/17 00:53:13
OOP 言語が SQL に近づいたこと
(より「意図通りに書ける」ようになった)も重要だし、
in-memory オブジェクト、XML、DB に対して
ほぼ同じ書式でクエリが書けることも重要かと。

66:デフォルトの名無しさん
08/02/17 20:41:50
LINQとSQLの違いのひとつにプランナの有無がある。
LINQは処理順に書かなくてはならないし、必ず記述順で処理される。
LINQはSQLの類似品と考えるより、
Enumeratorやコールバック(ラムダ)を使ったパイプライン処理であり
コレクション処理の延長だと思ったほうが誤解がない。

67:デフォルトの名無しさん
08/02/17 21:31:55
>>63-66
いずれ統一化できる下準備になるのではないかと思っています。
最終的には、コンパイル済みの.NETのコードを直接 DB に送り込み、DBがそれを直接解釈するという形になるのではと想像しています。
そうしますと、C#/VB.NETで書かれたSQLとDBのSQLの微妙な解釈の違いが完全になくなると思うので、これは安心できると思うのですがどうでしょう?
あと、コンパイル済バイトコードを送りつけるなら、DBのスピードもあがるかもとかとか・・・
また、セキュリティーの関係ではSQLインジェクションの類は完封できそうです。

>>1 です、今日は、表の分割、行の分類のやり方を紹介します。

68:デフォルトの名無しさん
08/02/17 21:32:46
Q.表を分割したい
 LINQの文法は、例えば以下のような形式になっています。
 from アイテム名 in 元データ where アイテム名.項目=="条件のあっているデータ" select 新しい行の定義
 上記の文の最後の部分「select 新しい行の定義」の部分を「group 新しい行の定義 by ふるい分けの基準となる値」
 とする事により表を分割できます。
 
 ここでは
  1 "ABC"
  2 "DEF"
  3 "ABC"
  4 "DEF"
  5 "GHI"
 となっている表を、以下の三つの表に分割する方法です。
ABC のある列
 1 ABC
 3 ABC
DEF のある列
 2 DEF
 4 DEF
GHI のある列
 5 GHI


69:デフォルトの名無しさん
08/02/17 21:33:19
 ツールボックスから DataGridView と TextBox を三つ貼り付けて以下のコードを実行すると三つの表が完成します。
 var tableOrg1 = new[] {
  new { LineNo = 1 , Data = "ABC" } ,
  new { LineNo = 2 , Data = "DEF" } ,
  new { LineNo = 3 , Data = "ABC" } ,
  new { LineNo = 4 , Data = "DEF" } ,
  new { LineNo = 5 , Data = "GHI" } ,
 };
 var dataGridViewArray = new[] { dataGridView1, dataGridView2, dataGridView3 };
 var textBoxArray = new[] { textBox1, textBox2, textBox3 };
 var tableArray = (from row in tableOrg1 group row by row.Data).ToArray();
 for (int i = 0; i < dataGridViewArray.GetLength(0) && i < tableArray.GetLength(0); ++i) {
  dataGridViewArray[i].DataSource = tableArray[i].ToArray();
  textBoxArray[i].Text = tableArray[i].Key.ToString();
 }
by row.Data の部分を変更することにより、例えばby row.Data.Length などとする事により複雑なふるい分けが可能です。


70:デフォルトの名無しさん
08/02/17 21:34:14
Q.特定項目で分類したい
 項目に大小比較ができれば、ソートしてしまえば良いのですが、それが無い場合には少し困った事になります。
 ここでは、前出の「表を分割したい」と組み合わせた方法を紹介します。
 それは、前出のLINQ文「from row in tableOrg1 group row by row.Data」の後ろに「into tmp1 from tmp2 in tmp1 select tmp2」を追加して
 from row in tableOrg1 group row by row.Data into tmp1 from tmp2 in tmp1 select tmp2
 とすると実現できます、まじないの部類ですが・・・うまく行きます。

 var tableOrg1 = new[] {
  new { LineNo = 1 , Data = "ABC" } ,
  new { LineNo = 2 , Data = "DEF" } ,
  new { LineNo = 3 , Data = "ABC" } ,
  new { LineNo = 4 , Data = "DEF" } ,
  new { LineNo = 5 , Data = "GHI" } ,
 };
 var table1 = from row in tableOrg1 group row by row.Data into tmp1 from tmp2 in tmp1 select tmp2;
 dataGridView1.DataSource = table1.ToArray();


71:デフォルトの名無しさん
08/02/17 21:35:03
linq の文法 query-body ::= query-body-clause* final-query-clause query-continuation?
この query-body-clause* の部分が複数になると急に難解になりますね。
どういう時に、使うと見通しが良くなるのか、あるいはどういう時にろくな事にならないのか
パターンとアンチパターンを揃える必要がある気がします。

72:デフォルトの名無しさん
08/02/17 21:40:18
>>71
>この query-body-clause* の部分が複数になると急に難解になりますね。

とりあえず改行とインデントとletで工夫かな。

73:デフォルトの名無しさん
08/02/18 18:11:36
>>1 です、今日は、LINQ文法の詳細をやろうと思ったのですが……

一通りざらっと見てみて、LINQの文法はひょっとして質が悪いのでは?という疑惑が湧いてきました。
LINQの核心部分は、from join その他 LINQ キーワードではなく、実際の処理が記述されている System.Linq.Enumerable であるので
これが致命傷になるとは思えないのですが、簡単に使うための上っ面としては今一な気がします。
このキーワードと文法には、変な汎用性があり、相当な広範囲にわたって複雑な処理が可能ですが
それを行うなら、メソッドベースで行ったほうが良さそうな気がします。

1.方向性としては、良くある定型について、LINQ 文法を使って完結に記述。使用例一覧に纏めておき、サクッと使う。
2.例外的なクエリについては、メソッドを使い、一つ一つ区切りながらクエリを完成させる。

こういう使い方が良いのではと思い始めました。
皆さんはどんな意見をお持ちでしょうか?

74:デフォルトの名無しさん
08/02/18 18:13:51
URLリンク(www.microsoft.com) より。
今日はこれを、初心者向けの説明にしようと思ったのですが……難しすぎ
区切り無く、際限なく、限りなく書き方が広がるとマニュアル化ができません。
query-continuation? の定義に query-body があるのが最悪だ。
だれがこれを手際よく解説するアイディアお持ちで無いでしょうか?

query-body ::= query-body-clause* final-query-clause query-continuation?
query-body-clause ::= (from-clause | join-clause | let-clause | where-clause | orderby-clause)
join-clause ::= join itemName in srcExpr on keyExpr equals keyExpr (into itemName)?
let-clause ::= let itemName = selExpr
where-clause ::= where predExpr
orderby-clause ::= orderby (keyExpr (ascending | descending)?)*
final-query-clause ::= (select-clause | groupby-clause)
select-clause ::= select selExpr
groupby-clause ::= group selExpr by keyExpr
query-continuation ::= into itemName query-body

#ひょっとしてカンマ忘れてる?
#orderby-clause ::= orderby (keyExpr (ascending | descending)? ,)*

75:デフォルトの名無しさん
08/02/18 18:52:44
>>73
LINQ って言葉の指す範囲は広くて、クエリ式もメソッド形式もどっちも LINQ よ。
from x in list みたいなのはクエリ式。

クエリ式でないと書きづらいのは、多重 from と join と let くらいかな。
まあ、transparent な変数が絡むとクエリ式使わないときつい。
逆に、クエリ式で書けないことも実に多い。

まあ、個人的には、
クエリ式で書けるものは全部クエリ式で、
それ以外だけメソッド形式で書いてる。

76:デフォルトの名無しさん
08/02/18 18:56:38
>>74
俺は
基本的に、select と group by は最後に来る。
その後ろにさらにクエリを続けたい場合は into x を置いてからさらに続ける。
と説明してる。

77:デフォルトの名無しさん
08/02/18 19:00:39
対応関係としては、

from x in list where x > 0 select x;

list.Where(x => x > 0); // 最後の Select はきえる

from x in list select x * x;

list.Select(x => x * x);

from x in list select x * x into y where y > 5 select y;

list.Select(x => x * x).Where(y => y > 5); // .Select の後ろにさらにメソッドが続く

78:デフォルトの名無しさん
08/02/20 00:08:01
>>1
お前社員だろwwwwwww
こんなの広めてどうするwwwwww

79:デフォルトの名無しさん
08/02/20 04:36:32
Hibernate とは違うの?

80:デフォルトの名無しさん
08/02/20 10:09:28
>>79
後出しじゃんけんの分強い
対象が Java か .NET か
LINQ では、C# や VB の言語仕様もいじったから書きやすい

81:デフォルトの名無しさん
08/02/20 18:48:34
>>1です、一週間では見えてくるものが少ないですね、暫く使い込んでみることにしました。
Linq to SQL , Linq to XML , 生Linq と全部使い込みをしないと見えてきにくいですね。

>>78
おれ社員じゃないよ、ボーランド大好きヘジたん信者の可能性は高いけど(笑
それと食わず嫌いはどうかなwwww
問題もそれなりに多そうだなというのも見えてきましたけど開発効率めちゃくちゃ高いよぉ。

82:デフォルトの名無しさん
08/02/20 20:25:54
>>79
簡単に言うと、O/Rマッピングは対症療法、LINQは原因療法、みたいな。
なんでこんなのが必要かってのは、
URLリンク(d.hatena.ne.jp)
を読むと理解が深まるかも。

83:デフォルトの名無しさん
08/02/20 21:16:01
LINQ最大の効果ポイントは、一般化と高速化にあるんじゃないかな
データベースから、XMLから、果ては適当なクラスや構造体まで統一手法で操作可能という点。
O/Rマッピングと目指すところがそもそも違うと思う

84:デフォルトの名無しさん
08/02/20 22:14:52
キャッシュポリシーは単純だけど、Linq to SQLはORM。
これだけはほかのと系統が違う。これで使うラムダ式は特殊なもの。

85:デフォルトの名無しさん
08/02/20 23:37:59
( ゚д゚)ノ ハイ!シツモーン!です。
次のように追加してくと実行時間がリニアに増えてくんだけど何か間違えてるんでしょうか?
プロジェクトごとあげてみました。
URLリンク(www.borujoa.org)
class Program {
static void Main(string[] args) {
var db =new TestDB(@"testDB.sdf");
db.DeleteDatabase();
db.CreateDatabase();
var count=0;
var tu=new TickUtil();
tu.WriteLine("begin--");
while(count++<5000){
var person=new Person{Name=string.Format("name-{0:8d}",count),
Age=count,Explanation=string.Format("Explain-{0}",count)};
db.Persons.InsertOnSubmit(person);
db.SubmitChanges();
if(count%100==0)
tu.WriteLine("new person-count={0}",count);
}
tu.WriteLine("end-");
}
}


86:デフォルトの名無しさん
08/02/21 01:06:41
LINQでWin32のメッセージマップって書けないの?

87:デフォルトの名無しさん
08/02/21 01:43:02
C++/CLI には無いの?

88:デフォルトの名無しさん
08/02/21 07:12:47
>>85
遅くなるというのは1件あたりの処理時間が増えるということかな?
それだったらCompact Editonなのが影響してるのかもしれない。
2005Expressで実行してみたらどうだろう。

db.SubmitChanges(); は5000件まとめての方が速いと思う。
メモリがきついようなら500件くらいまとめてで。


89:デフォルトの名無しさん
08/02/21 08:46:06
>>88
百件のインサートごとにその間にかかった時間を書いてるんですが、それがリニアに増えてきます。
Express or Serverで試してみます。

実際の実行時はまとめたほうがよさげですね。

90:デフォルトの名無しさん
08/02/21 10:05:01
>>85のソースから
> protected string SetAndReturnDifferenceTimeString() {
> int current = Environment.TickCount;
> int lastDiff = current - _last;
> _last = current;
> return "[" + lastDiff + "]";
> }
> public void WriteLine(string message) {
> Console.WriteLine(message + " " + SetAndReturnDifferenceTimeString());
> }
> public void WriteLine(string message, params object[] args) {
> WriteLine(string.Format(message, args));
> }

100件毎に実行されるのってWriteLine(string message, params object[] args)じゃね?
最近プログラミングしてないんで間違ってたらスマソ

91:デフォルトの名無しさん
08/02/21 10:13:41
>>90
下のWriteLine()の中で上のを呼んでる。

92:デフォルトの名無しさん
08/02/22 00:11:14
>>1 です
クエリ式はとりあえず放って置いて、メソッドでしか表現できないタイプのものを解説してみようと思っているのですが
まずは一発目で Aggregate あたりからやってみようかと思ってます。
ただ、このメソッドあまりにも関数型言語らしい仕様をしています。
何か良い説明方法はないかと色々さがしているのですが、良いのがあったら誰か紹介してください。
URLリンク(d.hatena.ne.jp)
とりあえず、この辺りとか見てみたのですが……
こんなの見せられたら初心者さん気絶するよなとか思いつつ、何かいいのはないかなと……

93:デフォルトの名無しさん
08/02/22 00:32:05
>>92
forループからの置き換えで解釈してみては。

int sum = 0;
for (int i = 1; i <= 100; i++) {
  sum += i;
}

これをAggregateで記述するとどうなるか、とか。

94:85
08/02/22 00:39:59
Comapctでまとめて実行するようにしたらリニアに増加するのはなくなった様。
10000件ぐらいまではまとめたほうがトータルの実行時間が短くなった。
もっと多くした場合はどうなるかは今度試します。
ほかのデータベース試してないけれど、なんかCompactのせいっぽい匂いが・・・

95:デフォルトの名無しさん
08/02/22 01:20:37
>>92
その情熱がどこから来るのかわからんが、Aggregateなら
・sum、factあたりを通常の再帰関数で書く
・共通する部分を抜き出す
・これがAggregateです
っていうのがわかりやすいんじゃないの?

96:デフォルトの名無しさん
08/02/22 11:23:52
>>92
URLリンク(ufcpp.net)

97:デフォルトの名無しさん
08/02/22 19:46:15
クエリ式はきもいけどLINQ自体はないと生きていけんよ
コレクションに対するアルゴリズムは絶対に必要だ
XMLやSQLは別になくても生きていけるとは思うが

98:デフォルトの名無しさん
08/02/22 22:13:52
>>92

99:デフォルトの名無しさん
08/02/23 01:08:33
>>1 です
>>93 結局ループをどの様に書くかという問題なのだからそれが一番いいような気がしました。
それと、これは群論の本(数学の本です)を読んでいて、抽象化は具体例を限りなく沢山作ってその中から共通の物を取り出すことだという記述があって
それも考慮にいれて、まず具体例、それからループへと展開する方針でいってみようと思います。

>>95
申し訳ないですが、再帰は最終手段だと思います、非常に良くないと思います。それ以外の部分は賛成です。
再帰とラムダ(or Delegate)は絶対に最初に記述して説明してはならないものだと確信しています。

>>96
>URLリンク(ufcpp.net)
>実を言うと、僕は趣味でプログラミングをしてるだけで、 C# は研究とは一切関係なかったりします。
>(むしろ C/C++ を使うことが多かった。 2007年追記: 最近では割となんでも C# で書くようになりました。)
>初めて C# について調べてみたとき(ちょうど Java に物足りなさを感じ、SUNの方針に憤りを感じていたころです)、
> C# が普及してくれればプログラミングにかかる手間は大幅に削減されると感じるました。
>しかし、Microsoft は順調に行かなさそうなものはばっさりと切り捨てることで有名な企業ですし、
>世間の C# への関心が低ければ、C# は普及することなく消え去ってしまうでしょう。
>そこで、少しでも早く C# が普及するようにとの願いを込めて当コンテンツを作成することにしました。
実は自分も全く同じ境遇です、でも研究者じゃありません、ただのプログラマですが……
関数型言語をやっていて思うところで、こんなの一発なのにというコードがオブジェクト指向のスタイルでは全くまともにかけなくて歯がゆい思いをしていました。

今日からお休みなので、これから練ってみます、明後日辺りから書き始めるかもしれません。

100:デフォルトの名無しさん
08/02/23 01:09:33
しかし、URLリンク(msdn2.microsoft.com)
これをみて理解できる人間が一体何人いるんだろうか……

Aggregate<(Of <(TSource, TAccumulate>)>)(IEnumerable<(Of <(TSource>)>), TAccumulate, Func<(Of <(TAccumulate, TSource, TAccumulate>)>))
この表現からぱっと見た目に使い方がわかる人は一体何人いるんだろうと、首を傾げそうになります。
ドキュメントのつくりを一度見直すべきだと思う……強力なのに……

>世間の C# への関心が低ければ、C# は普及することなく消え去ってしまうでしょう。
こんな状態になって欲しくないです
これを使えば、エクセルで小計等をやるような操作を一行で書き下せますが、使える人が居なくなってしまう。

101:デフォルトの名無しさん
08/02/23 01:22:13
C++にBoostその他の取り合わせなんか、正にそんな世間の関心が低い状態。
LINQもそういうことになってしまうのは嫌だな。

102:デフォルトの名無しさん
08/02/23 02:31:52
一応世間に知られてからもう大分経つでしょ・・・
これ流行らないよ・・・
from の位置とか外人さんでも気持ちわるいんじゃないかな

103:95
08/02/23 02:36:28
>>99
あー、ごめん、関数型言語とごっちゃになってた。
C#なら95の最初の手順を
・sum、factあたりを通常の関数で書く
でいいな。確かに再帰とかいらない。

蛇足ですが、あなたの対象とする「初心者」像がいまいちわからないのが
少し気になります。

104:デフォルトの名無しさん
08/02/23 03:22:34
>>102
発売後15日にして大分経っていたのか、それはショックだw
ごみレスつけるな、よそ行けよ

105:デフォルトの名無しさん
08/02/23 10:15:51
Selectが X->Y のマップになってるのはちょっと名前がわかり辛くて見つけられなかったな
duck typing(?)とかいう手法で Map :: X[] -> (X -> Y) -> Y[] を作っちゃった

拡張性も結構あるしガクジュツ的ではなくちゃんと実務に沿って開発しやすくなるような言語拡張だからLINQは流行ると思う

106:デフォルトの名無しさん
08/02/23 13:41:16
Enumerable.ForEachがほしい

107:デフォルトの名無しさん
08/02/23 14:51:39
要望出してSP1に入れさせようぜ

108:デフォルトの名無しさん
08/02/23 14:52:38
>>106 自分で作りなはれ。自分は作った。


109:デフォルトの名無しさん
08/02/23 14:56:38
晒して

110:デフォルトの名無しさん
08/02/23 15:10:50
void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
 foreach(T item in source) action(item);
}
ただこれだけのことだけど
こんなことしちゃうとコード全体がガラッと変わるから非公式にやるのは抵抗がある

111:デフォルトの名無しさん
08/02/23 15:17:25
なんでもかんでも一行でやろうとするのはC#的じゃないだろ
foreachぐらい分けて書こうぜ

112:デフォルトの名無しさん
08/02/23 15:42:04
URLリンク(www.microsoft.com)

ヘジ自ら書いてる
これが俺のバイブル

113:デフォルトの名無しさん
08/02/23 16:44:36
foreachのみで簡潔に書けるものはforeachのみで良いと思います

foreach( var row in table ) 文 ;

これ以上何かをする必要はないだろうと思う、逆にややこしいだけだし。

はなしは変わって、URLリンク(ufcpp.net) によると
> でも、メソッド提供だけでは、 join や let などがどうしてもきれいに表現できなかったので、
<やむなく SQL 風のクエリ式を導入したそうです。
>(プログラミング言語の中に別に言語を埋め込むというのはデメリットも大きくて、
>言語制作者にとっては結構ためらわれる行為。)
>(join や let をきれいに書くためには、どうしても透過識別子のような考え方が必要だった。)
という事らしいのですが、私は、むしろ逆で、これを見た瞬間λ式消滅、これは素晴らしい!!
と思ったものなんですが……
"Language Integrated" Query というぐらいですから、最初こちらがあったのだと想像していのですが逆だったんですね。
foreach にはλ式は登場しないので十分だと思っています。

114:デフォルトの名無しさん
08/02/23 16:47:27
デザイナを使っているとdelegateやeventなんて全然意識しやいじゃないですか
ダブルクリックすれば勝手にコード登場となって、こういうややこしいものは後回しにして使い方を最初に知ることができる。
これがC#の良い点だと思うんですよ。

115:デフォルトの名無しさん
08/02/23 16:50:49
List<T>やArrayにはForEachがあるだろ
匿名メソッドよりも,普通のメソッドを直接渡すときに気持ちいいんだよね
list.ForEach(Console.WriteLine);みたいに
初めてみたときはびっくりしたけど

116:デフォルトの名無しさん
08/02/23 16:59:23
普通にプログラミングしててもSelectやWhereは腐る程出てきて
それらを書くぶんにはクエリ式でなく拡張メソッド+ラムダ式の方がシンプルに書ける
ラムダ式は他にもプログラミングのあらゆる局面で使うと便利なことが多い
対してクエリ式はSelectManyやJoinなんかで使うとシンプルに書けるけど
そんなん滅多に使わん

117:デフォルトの名無しさん
08/02/23 17:43:25
遅延評価のせいで,一旦必要な部分を評価しないといけないのか・・・

new[] { 1, 2, 3, 4, 5 }.Select(
    x => {
        Console.WriteLine(x);
        return x;
    }
).ToArray();

118:デフォルトの名無しさん
08/02/23 18:06:36
遅延評価の問題すっかり忘れてた、あんまり意識する必要無いとおもったけど、デバッグ時にも面倒が起りますね。
あなたがその値を見るまでは値は計算されていませんって、まるでシュレディンガーの猫のような現象がありました。

119:デフォルトの名無しさん
08/02/23 18:24:47
普通に書いたらええがな

120:デフォルトの名無しさん
08/02/23 18:29:18
.ToList().ForEach(Console.WriteLine) でいいじゃん

121:デフォルトの名無しさん
08/02/23 18:30:33
ToList超きもい

122:デフォルトの名無しさん
08/02/23 18:32:42
遅延評価はLINQだと実態があいまいになりがちだがHaskellを使うと、なんというかテツガクしたくなる。
ものすごく面白いが、万人にお勧めではない。

123:デフォルトの名無しさん
08/02/23 18:35:44
IEnumerable<>でforeachするときの例っぽいの書こうとした^p^

124:デフォルトの名無しさん
08/02/27 19:00:07
>>1 です
 ちょっとスタイル変更、くだすれC#だと、配列よりも List クラスの方が需要ありそうだったので。
 実際、実用上は配列って事はありえない気がしますし。
 名前は全部漢字にして、型名には末尾に"型" と付けてみました。


125:デフォルトの名無しさん
08/02/27 19:00:49
Q.売上表で小計をもとめるような計算をしたい(1)
 Aggregate が便利です。
 以下の例では、合計原価と合計売価を求めます。解りやすさ優先で、型をすべて書ききったバージョンです。

 System.Collections.Generic.List<売上帳の行型> 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
 売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
 売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
 // お試し表示
 dataGridView1.DataSource = 売上帳;
 // 合計の計算方法
 合計型 合計の初期値 = new 合計型() { 合計原価 = 0, 合計売価 = 0 };
 合計型 合計表 = 売上帳.Aggregate(
  合計の初期値,
  (合計型 直前の合計, 売上帳の行型 行) => new 合計型() { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 }
  );
 dataGridView2.DataSource = new 合計型[] { 合計表 };

 public class 売上帳の行型 {
  public string 品名 { get; set; }
  public int 数量 { get; set; }
  public int 原価 { get; set; }
  public int 売価 { get; set; }
 }
 public struct 合計型 {
  public int 合計原価 { get; set; }
  public int 合計売価 { get; set; }
 }

126:デフォルトの名無しさん
08/02/27 19:01:50
>>125の続き 売上表で小計をもとめるような計算をしたい(2)
省けそうな型名は省略したバージョンです

var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
var 合計表 = 売上帳.Aggregate(
 new { 合計原価 = 0, 合計売価 = 0 },
 (直前の合計, 行) => new { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 }
 );
dataGridView2.DataSource = new[] { 合計表 };


127:デフォルトの名無しさん
08/02/27 19:03:01
>>126の続き 売上表で小計をもとめるような計算をしたい(3)
上記のコードが何をしているのかといいますと、以下のコードのような処理をしています。

var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// お試し表示
dataGridView1.DataSource = 売上帳;
// 合計の計算方法
var 直前の合計 = new { 合計原価 = 0, 合計売価 = 0 };
foreach (売上帳の行型 行 in 売上帳)
{
 直前の合計 = new { 合計原価 = 直前の合計.合計原価 + 行.数量 * 行.原価, 合計売価 = 直前の合計.合計売価 + 行.数量 * 行.売価 };
}
dataGridView2.DataSource = new[] { 直前の合計 };

128:デフォルトの名無しさん
08/02/27 19:04:24
>>127の続き 売上表で小計をもとめるような計算をしたい(4)
これを使うと簡単になるケース
合計型と売上帳の行型が同じなら、コードは単純になります

var 売上帳 = new System.Collections.Generic.List<売上帳の行型>();
売上帳.Add(new 売上帳の行型() { 品名 = "デスクトップPC", 数量 = 1, 原価 = 100000, 売価 = 120000 });
売上帳.Add(new 売上帳の行型() { 品名 = "ノートPC", 数量 = 2, 原価 = 250000, 売価 = 280000 });
// 合計の計算
var 合計行 = 売上帳.Aggregate((直前の合計, 現在の行) => new 売上帳の行型() { 原価 = 直前の合計.原価 + 現在の行.数量 * 現在の行.原価, 売価 = 直前の合計.売価 + 現在の行.数量 * 現在の行.売価, 品名 = "合計" });
売上帳.Add(合計行);
// お試し表示
dataGridView1.DataSource = 売上帳;

129:デフォルトの名無しさん
08/02/27 19:05:23
まとめ
駄目だ、どうあがいても単純になりません。
3 番目を書いてみたら、foreach で書いたほうが見通しがよさそうな感じすらしてきます。
綺麗になるのは、アキュムレーターの型とコンテナ要素の型が一致しているとき
もしくはアキュムレーターの型が int のような単純型で有る場合に限られます。
メソッド方式にはやはり何かが足りない感じがします。
LINQの新規キーワードとして、それも foreach をイメージできるような構文にして
"aggregate 売上帳" と書いたら、型名、その他をインテリセンスがズバズバッと書き出して、
作る側は中身をを書くだけといった具合になれば使えそうな気がするのですが……
もしくは Excel の、式のコピーのようなイメージができれば、やる事は一番上の式を書く事となるのですが。


130:デフォルトの名無しさん
08/02/28 02:02:30
ところでこのコードってVB?


131:デフォルトの名無しさん
08/02/28 11:52:14
驚くべきことに今まで一行もVBのコードは出てきていないんだ

132:デフォルトの名無しさん
08/02/28 12:47:55
ほいじゃVB版Linq for XML
XMLリテラルが売りですのじゃ
Dim xm = <AAA>
  <BBB id="1">aaaaacxzc</BBB>
  <BBB id="2">aaaaaxczx</BBB>
  <BBB id="3">aaaaaxcxz</BBB>
  <BBB id="4">aaaaaxczx</BBB>
  <BBB id="5">aaaaaxxxx</BBB>
  <BBB id="6">aaaaazzzz</BBB>
  <BBB id="7">aaaaacccc</BBB>
  <BBB id="5">aaaaaxxxx</BBB>
  <BBB id="6">aaaaazzzz</BBB>
  <BBB id="7">aaaaacccc</BBB>
</AAA>
Dim rs = From x In xm...<BBB> _
  Where x.@id > 2 _
  Distinct Skip 1 Take 3 _
  Order By x.@id Descending _
  Select ID = x.@id, x
For Each r In rs
  Console.WriteLine(r)
Next


133:デフォルトの名無しさん
08/02/28 13:15:08
クエリ式はC#よりVBの方が馴染んでるよなあ
VBのラムダ式は糞だけど

134:デフォルトの名無しさん
08/02/28 17:54:04
>>129
AggregateはSumやMaxと同じで集合関数として使うように設計されてるので
group by と組み合わせて使うのが普通なのだと思う。
この例だとSumが使えるのだがAggregateを使ってみた。
var 合計表 = (
  from uri in 売上帳
  group uri by 1 into g
  select new 合計型(){
     合計原価 = g.Sum(o => o.原価 * o.数量),
     合計売価 = g.Aggregate(0, (t,o) => t + o.売価 * o.数量)
  }).First();
Console.WriteLine("{0}, {1}", 合計表.合計原価, 合計表.合計売価);


135:デフォルトの名無しさん
08/03/07 01:17:17
C#なんだから大概の物は関数型チックにかくより普通に書いた方が
見やすいのは当たり前

136:デフォルトの名無しさん
08/03/07 11:55:15
Expression Treeってフィールドの値を変更できないのか
できたらおかしいのはわかるけどDynamicMethodの簡易版として使うには貧弱だな

137:デフォルトの名無しさん
08/03/07 12:01:30
>>136
そういう用途だと、LINQ の Expression から DLR の AST Expression に変換してしまうのがいいかも。

138:デフォルトの名無しさん
08/03/07 17:40:05
LINQってDataTableに対してグループ化をしてDataGridViewに表示したり出来るんですかね?
現在、DataTableに対してグループ化ってかなり無理矢理やらないと出来ないと思うんですが、
これができると、DataTableがかなり使いやすくなりそうです。
.NET3.5をインストールさせる動機になりそうなくらい・・・

139:デフォルトの名無しさん
08/03/12 12:24:53
みんな小難しいことばっかやってて、なんとなくLinq避けてたが、
実際に使ってみるとなかなかスイーツ(笑)な簡単さじゃないか。
List<T>なんか作って追加していって最後にToArray()してるようなのも
Linqで書き換えたら全部一行に出来そうだ。

140:デフォルトの名無しさん
08/03/13 01:52:23
あれ?出勤、昼だか夜だかわからなくね?

141:デフォルトの名無しさん
08/03/13 11:30:56
VB.NETもスレタイの仲間に入れてあげてください。

142:デフォルトの名無しさん
08/03/13 13:24:30
VB.NETは新機能が全く話題にならないよな

143:デフォルトの名無しさん
08/03/13 15:06:20
>>142
むしろ新機能はLINQ以外にあったっけか?
まぁ銀光とかあるけど


144:デフォルトの名無しさん
08/03/13 15:07:51
宣言時の型推論,ラムダ式とか?

145:デフォルトの名無しさん
08/03/13 15:16:04
Xmlリテラルとか。

146:デフォルトの名無しさん
08/03/13 15:18:19
C#2.0+C#3.0+αだな

147:デフォルトの名無しさん
08/03/13 16:24:25
ぶっちゃけXML生書き出来るようになったからって・・・
使う奴っている?

今一歩使い道が見つからん・・・

148:デフォルトの名無しさん
08/03/13 21:19:44
>Xmlリテラル

タイミング良くっつーかこんな記事がでてるね。

.NETプログラマーにとって、XSLTは終焉なのか?
URLリンク(www.infoq.com)

>XML Literalsは最初Haskell向けに開拓され、
>のちにMicrosoftにおいてC#で使用するために開発された。
>どちらの言語においてもうまく いかないことが判明したので、
>Visual Basicチームが飛び付いて、VB 9の礎石にした。

>これはそれほどまでに驚くことではない。
>というのもHaskell構文がVBScriptのインラインHTML表記の影響を
>もろに受けて いたからである。

まあヘジたんなら拒否るだろし、事実拒否ったんだろうなぁ。

149:デフォルトの名無しさん
08/03/14 22:40:14
テーブル値関数をLinq to SQLで利用しようとしてるんだけど、
実行したら、
ストアド プロシージャはクエリ内では使用できない。ってエラーになるんだよ。
これバグじゃないかな。

150:デフォルトの名無しさん
08/03/15 00:46:01
自己解決しました。ノシ
IsComposable=true がなかったのが原因みたいです。
なんだかなあ。
 

151:デフォルトの名無しさん
08/04/06 03:35:46
保守

152:sage
08/04/13 01:33:35
LINQでのサブクエリの書き方が分からん。どう書くの?

SELECT
 A.KEY1, A.COL1, B.COL2
FROM
 (
  (SELECT * FROM TBL1) A
  INNER JOIN
  (SELECT * FROM TBL1) B
  ON B.KEY1 = A.KEY1
 )

153:デフォルトの名無しさん
08/04/13 02:32:31
そのままlinqに置き換えれば

var r =
 from i in
  (from a in TBL1
   from b in TBL2
   where a.KEY1 == b.KEY2
   select new { A = a , B = b })
 select new { KEY1 = i.A.KEY1 , COL1 = i.A.COL1 , COL2 = i.B.COL2 };

こんな感じだけど、この例だとサブクエリ必要なくね?

154:デフォルトの名無しさん
08/04/13 02:36:53
>>152
それ、LINQ だとサブクエリ要らない。

var q =
 from a in tbl1
 join b in tbl2 on a.Key equals b.Key
 select new { a.Key, a.Col1, b.Col2 };

サブクエリは普通に ↓ みたいに書ける。
from a in
 from b in list
 select b.SomeProperty
select a.SomeProperty

155:デフォルトの名無しさん
08/04/13 14:50:18
そんなことしなくても
保守が容易な綺麗なコードを書けるから
(゚⊿゚)イラネ

156:デフォルトの名無しさん
08/04/13 16:44:19
最近LINQ初めて>>22見たんだけど、
コードが見通しよく整理されていく中盤からの展開は見てて痛快だなぁ

157:デフォルトの名無しさん
08/04/24 21:22:23
URLリンク(code.msdn.microsoft.com)


158:デフォルトの名無しさん
08/04/24 21:41:48
>>157
Visual LINQ Query Builder

VS2008用のアドインか

159:デフォルトの名無しさん
08/05/24 20:45:08
Linqで書くと速くならないなら需要ないんじゃない
SQLでおなかいっぱいで

160:デフォルトの名無しさん
08/05/24 21:01:08
>>159
LINQ の価値は速度じゃなくて、
OOP パラダイムと RDB パラダイムの懸け橋になること。
SQL でおなかいっぱいって人にこそ LINQ がいいんじゃないか。

161:デフォルトの名無しさん
08/05/24 23:11:23
パラ?
お母さんが子供に教えるように教えてください

162:デフォルトの名無しさん
08/05/24 23:23:16
>>161
C# の中で、オブジェクト指向言語の感覚からあまり外れることなく、
データベース問い合わせが書けるってことが大事。

163:デフォルトの名無しさん
08/05/25 00:22:26
最初は書き方に戸惑うが、だいたいの書き方がわかってくればインテリセンス使えるのがとても大きい

164:デフォルトの名無しさん
08/05/25 04:39:07
コンパイラによる構文チェックが行われるというのも大きい。
条件次第で内容が大きく変わるようなクエリを構成するときに、文字列の連結を間違えて
バグを作り込んでしまうような、つまらないミスを防げる。
DataContextの定義にあわせて自動でCREATE DATABASEしてくれるとか、生産性の向上に
つながる要素がいろいろあるよ。
俺もほとんど把握してないけどさ。

165:デフォルトの名無しさん
08/05/25 09:04:21
SQLって、汎用コレクションデータ処理エンジンだね。
C/C++やらで何らかのデータ処理を行う場合、その度毎にアルゴリズムを考え、設計し、
コードを作りこまなくちゃいけないけど。
RDBだと、ちょこっとSQLを定義するだけで実際の処理はRDBのエンジンがやってくれる。
例えるなら文字列の正規表現みたいな感じで。

それが言語組み込みの文法として、RDBだとDBサーバを立て、テーブルを作り、データをインポートして
からじゃないと使えないのが、RDBに限らずC#言語上の任意のコレクションデータで使えてしまう
ってのは便利。

166:デフォルトの名無しさん
08/05/25 09:41:44
>>161
インピーダンスミスマッチでぐぐれ

167:デフォルトの名無しさん
08/05/25 11:12:57
SQLMetalってすでにあるテーブルのオブジェクト定義のXMLを生成するものだよね?
逆に今あるオブジェクトからテーブルとかを生成するツールってあったっけ?

168:デフォルトの名無しさん
08/05/25 14:02:32
>>167
方法 : データベースを動的に作成する (LINQ to SQL)
URLリンク(msdn.microsoft.com)

169:デフォルトの名無しさん
08/05/25 14:39:10
>>161
これでも読め
URLリンク(www.microsoft.com)

170:デフォルトの名無しさん
08/06/02 22:49:47
Linq人気ないから救済でAgeてやる
感謝しろビル

171:デフォルトの名無しさん
08/06/04 08:38:01
PL/SQLですね。

172:デフォルトの名無しさん
08/06/09 11:06:00
スレリンク(tech板)

173:デフォルトの名無しさん
08/06/15 19:33:30
えーい
Linqも人気ないけど
ダメ技術のかほりがすっぞ

174:デフォルトの名無しさん
08/06/17 02:07:55
使ったからといって、別に何かが楽になったりすっきりしたりするように見えないんだよな。

175:デフォルトの名無しさん
08/06/17 07:25:18
ちょっとしたDBアプリ作るの楽になるが。
XMLとかにもいいと思うよ。

176:デフォルトの名無しさん
08/06/17 21:00:53
メソッド形式は手軽に使えてすごく便利だよね
クエリ形式は「さあLINQ使っちゃうぞー」って感じになっちゃって好きじゃない

177:デフォルトの名無しさん
08/06/17 22:19:07
未だにクエリ式だとpとかqとかのスコープがよくわかってない俺。

178:デフォルトの名無しさん
08/06/18 03:55:30
fromやletが沢山必要になる場合は
クエリ式を使ってる

けど、それ以外ではクエリ式は全然使ってない

179:デフォルトの名無しさん
08/06/19 22:35:19
使い方も確立されてない未知のもんだからな。
ポテンシャルは高い気がする。

180:デフォルトの名無しさん
08/06/20 00:55:26
LINQきれいにかけるけれど、特にObjectLINQだと効率的にはだめな場合もあるからなぁ。
微妙なところだ。
PLINQとかになるとまた話は違うだろうけれど。

181:デフォルトの名無しさん
08/06/20 08:43:29
>>180
from x in a select x; みたいなのを foreach(var x in a) yield return x; に変えるような
最適化だとせいぜい5%くらいしかスピード変わらない。
5%を気にしないといけない場面はそれほど多くないと思う。

ただ、a.Max(), a.Min(), a.Count() を同時に求めたいような場合、
自前で for まわして同時に求めた方が圧倒的に早い。

Parallel Extensions にはParallel.Forとかもついてるしなぁ。
PLINQでもやっぱり Max, Min, Count の問題は解消しない。

182:デフォルトの名無しさん
08/06/20 09:05:06
>>181
DryadLINQみたいにExpressionを直接扱う計算エンジンが要るね。
PLINQは所詮IEnumerableベースだし。
URLリンク(research.microsoft.com)

ポテンシャルはDryadLINQ>>>>>PLINQなんだろうけど、
出荷までにかかる時間を考えるとPLINQ>>>DryadLINQだろうねぇ。

C# 3.0もお披露目から1年半ぐらいかかったし。
出荷までの時間短縮はお金じゃ解決しづらいんだろうな。

183:デフォルトの名無しさん
08/06/20 09:07:06
>出荷までにかかる時間を考えるとPLINQ>>>DryadLINQだろうねぇ。

不等号逆だった……
ポテンシャル: DryadLINQ>>>>>PLINQ
出荷までにかかる時間: PLINQ<<<DryadLINQ

184:デフォルトの名無しさん
08/06/20 09:10:04
>C# 3.0もお披露目から1年半ぐらいかかったし。

あとこれもお披露目から2年半の間違い。

185:デフォルトの名無しさん
08/06/21 10:41:48
もうちょっと落ち着いて!

186:デフォルトの名無しさん
08/06/26 01:03:41
いや、勢いあったほうがよい

187:デフォルトの名無しさん
08/07/07 22:42:17
複雑なXMLファイルの読み込みはXmlTextReaderよりLINQ to Xmlを使ったほうが簡潔に書けそうですか?

188:デフォルトの名無しさん
08/07/07 22:53:07
書いてみろ

189:デフォルトの名無しさん
08/07/07 23:23:38
>>188
一言レスって周りにも意図伝わらないからヤメレ

190:デフォルトの名無しさん
08/07/07 23:26:55
最近、勉強ついでにLINQtoSQL使ってるけどクラスとして扱えるだけで便利すぎ。
リレーション張っても参照のプロパティでアクセス出来るのも簡単すぎて涙が出る。
長ったらしいデータセットのクラス名で変数宣言してたら、varで省略できるのにも涙が出た。

191:>>188 じゃないよ
08/07/07 23:30:39
>>189
自分で書けばわかるって事だろ?

意図理解できないのは君だけだと思うが。

192:デフォルトの名無しさん
08/07/08 10:10:04
XmlElementとXElementの違いを問うならわかるが、
XmlReaderと比べるあたり自分では何も調べずに
思いつきで書き込んだと証明してるようなものだ。

193:デフォルトの名無しさん
08/07/08 23:25:23
>>191
二つコードを書けということですね、わかります



194:デフォルトの名無しさん
08/07/08 23:47:33
なんか俺のせいで荒れてるみたいだな
ごめんなさい

>>192
違いの話なんかしてないっすよ?




あれからbuilderってサイトのサンプルを読んで勉強してみてる。
ちょっと興奮で震えてます。
皆ありがとう


195:デフォルトの名無しさん
08/07/09 03:40:44
複雑なXMLファイルの定義によるかな。
Linq for XMLで使うXElement系のクラスはDTDやXMLスキーマをサポートしない。
構造の検査、実体やデフォルトの属性を展開することが必要という意味で複雑なXMLだったら手も足も出ない。
XDocument/XElementはXMLパーサーとしての機能をしぼっている。
簡単なXMLの読み書き加工は簡単にかつスマートに書ける、Linq for XMLはその為のもの。

XmlDocment/ElementはDOMとしてのすべての機能をもつ。多機能ではあるが何をするにも大掛かり。

XmlReader/Writerは StAX型の前方参照型で高速。
使用メモリが少なくてすみ全部メモリに読み込むのが問題になるような大きなXMLも対応できる。
扱いは当然ややこしい。





196:デフォルトの名無しさん
08/07/11 13:29:59
意外に使いやすいよねXmlReader/Writer

197:デフォルトの名無しさん
08/07/19 20:38:17
マイクロソフト公式解説書としてLINQ本が出るってよ

LINQテクノロジ入門
URLリンク(ec.nikkeibp.co.jp)
・07/22発売 3,360円(税込み) B5変 280P

198:197
08/07/27 00:32:31
届いたんでぼちぼち読み始め

図表を多く使っていて、C#/VBのサンプルコードも多いのは○
内容的には結構踏み込んで丁寧に解説されていて、実際に発行されるT-SQLまで触れられてたりする。

・C#/VB・SQLに関する基本的な理解は必須。
・開発経験のない初心者が読むには少し難しい。
・何となくLINQを使っているが、使いこなせていないと感じてる人 にはおすすめ。

199:デフォルトの名無しさん
08/07/27 01:55:18
LINQのProviderでしたっけ?クエリーとかを実装する側の作業についてまとまってるarticleとかってありますかね?(´・ω・`)

200:デフォルトの名無しさん
08/07/27 11:06:25
>>199
単に .Select メソッド(あるいは拡張メソッド)とか実装するだけ。
LINQ to SQL みたいなことしたければ、
LINQ の勉強というよりは、Expression Trees の勉強が必要。

で、LINQ がらみの記事は結構おおいけど、
Expression Trees はあんまり見ないなぁ。

201:デフォルトの名無しさん
08/07/27 12:23:14
>>200
それです、それ。
具体的にどこまでのExpressionTreeをどんな風に実装したらいいのかが・・・



202:デフォルトの名無しさん
08/07/27 12:55:38
Expression Trees の方は、↓に多少サンプルあり。
URLリンク(ufcpp.net)

LINQ to SQL みたいなことしたければ、IQueryable でググってみるといいんじゃないかと。

203:デフォルトの名無しさん
08/07/27 13:14:37
MSDNのこれも読んでおくといいかも。
URLリンク(msdn.microsoft.com)
URLリンク(msdn.microsoft.com)

204:デフォルトの名無しさん
08/08/31 11:34:15
>>198
LINQの本が少ない中、この本はお薦め。
LINQを構成する基礎や、現在のバージョンで、できる事できない事、
やってはダメな事が書かれている。
.netとSQLを使って仕事している人ならLINQがどういう物か理解できる。
少なくともこの本レベルの事を理解していないと知らずに地雷を埋め込むことになる。

205:デフォルトの名無しさん
08/08/31 18:22:46
LINQは、VSに付いてくるC#のサンプルコードだけで十分理解できるでしょ。

206:デフォルトの名無しさん
08/08/31 23:44:43
LINQがこれから他のテクノロジとどう統合されてくのかよくわからん(´・ω・`)

207:デフォルトの名無しさん
08/09/01 00:10:28
> どう統合されてくのか

消えていくと言う運命もあるから、俺はもう少し様子見。

208:デフォルトの名無しさん
08/09/01 00:59:30
これだけ言語に食いこんだものが消えるというのはありえないと思うが。

209:デフォルトの名無しさん
08/09/01 06:48:16
いや、互換性のために機能としてはずっと残るかもしれないけど
新規には誰も使わなくなって結局放置と言うこと。

まあ、特攻する人も必要だから、>>208 は頑張ってくれ。

210:デフォルトの名無しさん
08/09/01 09:00:39
小手先の道具として便利なLINQ to objectsくらいは残るでしょ
そのほかはともかく

211:デフォルトの名無しさん
08/09/01 21:35:34
別に「残らない」なんて断定してるわけじゃないよ。
俺はなくてもあまり困ってないし、「残らない可能性もある」ので
ちょっと様子見してるだげ。

いいと思う人はどしどし使って広めてくれ。

212:デフォルトの名無しさん
08/09/01 23:25:27
LINQ便利ざんすよ?
特にLINQtoSQL。XMLはしらんがたぶん便利だろう。
今のだと出来ないこともあるけれど、出来るところのはかなり楽だ。

213:デフォルトの名無しさん
08/09/01 23:38:08
LINQ の意義の1つに、コレクションに対する操作がらみのメソッド名を統一したってのがあるから、
今後、LINQ to SQL とか LINQ to XML が廃れるようになろうとも、
コレクションとかサーバ問い合わせ系のライブラリ書く人は
おそらくほぼ LINQ の規約に従ってメソッド名を付けると思う。

そういう意味では、廃れないと思うんだが。
クエリ式とか、IQueryable を介したサーバ問い合わせとかが廃れようとも、
命名規約の部分に関しては絶対残る。

214:デフォルトの名無しさん
08/09/01 23:43:37
MS の技術が「なくても困らない」と感じるのは、
MS がエンタープライズ相手の商売してるから、
個人で趣味で開発してる人へのアピール弱いせい。
あんまりホビープログラムでDBアプリとか書かないし。

215:デフォルトの名無しさん
08/09/02 00:10:13
LINQはEntity Frameworkなんかと密接に関わるからねー
まだまだこれからの技術。

216:デフォルトの名無しさん
08/09/03 00:23:39
group by ... into g select new {value1 => g.hoge, value2 => g.fuga }
みたいなLINQ書くとselect newの部分でvalue1とvalue2を生成するためにSQLサブクエリが生成されるんだけど、
これってgroup byだけで上手く書き直す方法ないんかなぁ。

というより、生成したクエリを最適化してくれる関数みたいなものはないんだろうか。

217:デフォルトの名無しさん
08/09/03 08:19:42
LINQ to SQL 自体、Entity Framework までの繋ぎの過渡技術だし、
今後 Entity Fx の側がよっぽど大ごけしないと
LINQ to SQL のグレードアップは見込めない気もする。

LINQ とは別に、SQL 文の最適化ライブラリみたいなの探す方が早いかも。

218:デフォルトの名無しさん
08/09/03 08:25:31
EntityFWのクエリーインターフェースとして、LINQ使われるんじゃないの?(´・ω・`)
今のLINQのEntityうんたらがもっとしっかりしたものになるということ?

219:デフォルトの名無しさん
08/09/03 08:44:14
裏側の最適化の話ね。

同じ LINQ クエリ式を書いたときに、
実際にどういう SQL 文が発行されるかという、
実装上の最適化の部分に関して、
LINQ to SQL の今後にはあんまり期待しない方がいいんじゃないかってこと。

まだ手をつけてる人が少なくて情報少ないけども、
将来を期待したいなら LINQ to Entity Framework の方使うこと考えるのがいいんじゃないかと。

220:デフォルトの名無しさん
08/09/03 08:46:06
LINQtoSQLがせいじゅくされてLINQtoEntityになるのかとおもっとった

221:デフォルトの名無しさん
08/09/11 20:45:39
りんきゅー><

222:デフォルトの名無しさん
08/09/17 20:13:37
↓をメソッド形式で書きたいのですが、OrderByメソッドで複数のプロパティで
ソートするのははどうすればいいですか?

var v = from e in GetFoo() orderby e.Age, e.Name select e

OrderBy二回せずに一回でさくっと書きたいです。

223:デフォルトの名無しさん
08/09/17 22:32:24
>>222
OrderBy(1つ目の条件).ThenBy(2つ目の条件)

OrderBy 1回というのは無理。

224:デフォルトの名無しさん
08/09/18 20:14:01
>>223
ThenByって知らなかった。ありがと。

225:デフォルトの名無しさん
08/09/19 01:50:55
つか、そんなの条件式を二つ持つOrderByを自分で実装するがよろし


226:デフォルトの名無しさん
08/09/19 03:17:06
引数可変にしてOrderBy~ThenByに丸投げで、1分とかからずに実装できるな

227:デフォルトの名無しさん
08/09/19 07:24:56
こうして車輪は四角に変容しバグを抱擁した後に再輸出されるのであった...

228:デフォルトの名無しさん
08/09/28 23:54:29
LINQの遅延実行と即時実行は正直いらない気がする。
Aggreegate戻り値はIntegerだし、クエリ機能あれば十分なのでは。

LINQ TO XMLとか開発の現場でまず使うのは小数だろうし、可用性が低いよ。
VBチームの自己満足だね。いつものことだけど。

229:デフォルトの名無しさん
08/09/29 12:49:16
>>228
VBのAggregate構文のことかEnumerable.Aggregateのことを言ってるのかわからない。
Integerってどういう意味だろう、集計対象の型で集計されると思うけど。

VBのLinqは使いやすくしようと、文法やキーワードを増やしすぎて
収集がつかなくなってるという感じはする。C#と同じにしておけば良かったような。


230:デフォルトの名無しさん
08/09/29 14:30:31
VBはラムダ式が冗長だから拡張メソッドでクエリ書くと悲惨なことになる

231:デフォルトの名無しさん
08/09/29 14:54:49
遅延実行と即時評価ってやたら強調されてるけど
やっぱりC#のyield知らないとわかりにくいのかな

232:デフォルトの名無しさん
08/09/29 23:02:22
言われてみるとyieldを知らない(あまり使った事がない)とすれば
即時実行でないのに違和感を感じるのも分かるな。

233:デフォルトの名無しさん
08/09/30 11:58:27
いまさらだけど、yield Returnつう名前がややこすいよ!!

234:デフォルトの名無しさん
08/09/30 23:43:43
yield とかってどこからきたん?関数型?

235:デフォルトの名無しさん
08/09/30 23:47:50
Rubyのはクロージャ呼び出しだからPythonかなぁ。
Windows2x時代のAPIは関係ないと思う。


236:デフォルトの名無しさん
08/10/01 02:17:48
ICONからきていると予想
Fiberはいつのまにか消えていたってオチかな

237:[Fn]+[名無しさん]
08/10/02 00:00:54
てかDTDとかXMLスキーマサポートしてない段階でLINQ廃レは確定ぽ。。

238:デフォルトの名無しさん
08/10/02 00:06:53
それは LINQ to XML の問題であって、LINQ の問題じゃないのでは。

239:デフォルトの名無しさん
08/10/02 01:54:39
LINQ to XMLはもともとXmlDOMやXmlReaderの代替を狙ったものじゃなく、
standaloneのXMLや部分的なXMLを簡単に扱えることを目指したもの。
はじめからDTDやXMLSchemaはサポートしないことになっていた。
もっともnamespaceを中途半端なサポートはチトいただけないから改良は欲しい。
いっそなくすか、もっと充実させるかどちらかで。

240:デフォルトの名無しさん
08/10/02 08:21:03
スキーマはサポートしない、って確かにそうなんだけど
ぶっちゃけあれ下層に XmlReader が使えるからでは
ないのかと

241:デフォルトの名無しさん
08/10/02 13:10:43
LINQはすんばらしい
FOR EACH書かなくてすむし、べた書きのXMLもコードとして扱える。


242:デフォルトの名無しさん
08/10/03 00:46:47
C#だとエディットコンティニューが使えないのは結構痛い

243:デフォルトの名無しさん
08/10/03 10:10:47
エディットコンティニュかあ、x64だと使えないんだよなあ。
まあx86にすりゃいいんだけど、デフォがAnyCPUだからなあ。

244:デフォルトの名無しさん
08/10/11 23:59:11
てかLINQってORACLEとかポスグレでも使えるのね。

245:デフォルトの名無しさん
08/10/12 00:58:14
>>244
LINQ to Entity の出た今となってはね。
MS SQL Server でしか使えないって言われてたのは、
SP1 入る前、LINQ to SQL の時代の話。


246:デフォルトの名無しさん
08/10/12 02:57:11
別に Linq to SQL でも別データベースサポート可能だよ。
でも Linq -> Entity SQL がサポートされたから、Entity SQL ->
ネイティブ SQL だけでいいじゃん=皆やる気ナスなだけで。


247:デフォルトの名無しさん
08/10/12 20:47:40
Linq to Entityが生成する生のSQLを確認する方法を教えてください。

248:デフォルトの名無しさん
08/10/13 00:46:17
それは実行される前に?恒常的に?
そうじゃないならログ見りゃいいと思うけど・・・

249:デフォルトの名無しさん
08/10/13 17:15:00
>>248
実行時でかまいません。
Linq to SQLのようのDataContext.Logプロパティにあたるものが見当たらないようです。
またSystem.DiagnosticsのTraceやDebugでも確認できませんでした。
探し方が悪いのかもしれませんがSQLのログを出力する方法を教えてください。

250:デフォルトの名無しさん
08/10/13 21:39:14
だから SQL Server なら確かプロファイラ起動してトレースの開始で…
と記憶を頼りにぐぐって気づいたんだが Express にはないのか
このツール。おおう。それとごめんトレースだった

2005 ならこんなの見つけたけど
URLリンク(code.google.com)


251:デフォルトの名無しさん
08/10/17 03:19:46
タイプセーフなデータベースプログラミング
URLリンク(d.hatena.ne.jp)

拡張メソッドとラムダ式と式木と匿名型とvarとあって良かったと思える瞬間。

252:デフォルトの名無しさん
08/10/17 17:46:42
Entity FrameworkをLinqなしで使うと2番目の例っぽくなるね。

253:デフォルトの名無しさん
08/10/17 19:35:37
多言語でLinqのパクリを作ろうと思っても、言語仕様のサポートが無いと
ああいう風にせざるをえないんだよな。

254:デフォルトの名無しさん
08/10/17 22:35:24
まあ、だからC# 3.0がああなったわけで。

255:デフォルトの名無しさん
08/10/17 22:53:01
その辺Booなら自分で言語使用作れるかと

256:デフォルトの名無しさん
08/10/18 10:13:17
実際に動くものを作ってから言え

257:デフォルトの名無しさん
08/10/27 22:19:23
時間ができたので久しぶりの >>1 です、だんだん慣れてきた、半年続けた結果分かったことLINQスゲー使えます
という訳でみんなこれ勉強しろ!!
とりあえずアドバイス、まずは yield return / yield break が自在に使いこなせるようになるといいです。

使い方のコツ

 1.シーケンス( IEnumerable<T> 、データベースで言えばテーブル)の生成
 2.from ... または System.Linq.Enumerable で加工(繰り返し)
 3.ToArray() , ToList() , ToDictionary() , All() , Any() 等で結果生成。

これが標準パターン

 元の列を作る → 加工 → 加工 ・・・ → 加工 → 配列化

基本的にこればっかりです。
ちなみに LINQ が真の力を発揮するのはデータベースではなく、日常的に使う配列やオブジェクトです。
いままではデータベースではクエリで簡単に実行できても、プログラム中ではできずと
やむなくデータベースに一旦突っ込んでやるか、フルスクラッチで同等機能を作り出すかと、
無意味なプログラム実行環境の大規模化を引き起こしていました、これが無くなります。

258:1
08/10/27 22:20:21
とにかく『加工元が簡単に作れない』事には、LINQ は使い物になりません。
という訳でシーケンスの作り方のコツ
配列やList等は、IEnumerable<T> 持ちなのでそのまんまシーケンスその物である、これは当たり前。

*.バラバラな物をシーケンスにするコツ、『適当』に yield return をばらまく
 このあまりに馬鹿らしく単純な使い方になかなか気付けなかったw
 例
 class Test {
  int A;
  string B;
  // メンバーを片っ端からシーケンスにする
  IEnumerable<object> Members() {
   yield return A;
   yield return B;
  }
  public override bool Equals(object obj) {
   Test obj2 = obj as Test;
   if(obj2==null) return false;
   return this.Members().SequenceEqual(obj2.Members());
  }
  public override int GetHashCode() {
   return this.Members().Aggregate(0, (acc, element) => acc ^ element.GetHashCode());
  }
 }

*.IEnumerable<T> を持っていないライブラリの古い糞クラス用にアダプターやヘルパー関数をたっぷり作っておくこと!!
 例
 IEnumerable<T> CreateEnumerable<T>(Func<int> getCount, Func<int, T> getItem) {
  for (int i = 0; i < getCount(); ++i) yield return getItem(i);
 } 標準で .Net Framework に準備して欲しい・・・


259:1
08/10/27 22:21:21
二以上のシーケンスを同時に加工するときのコツ
1.ToArray() , ToList() 等で、一旦配列にする。
2.Enumerable.Range( 0 , seq.Count() ) で配列の添え字を列挙して使う(なかなか気付けなかったw)

 例
 var tmp1 = 元シーケンス1.ToList();
 var tmp2 = 元シーケンス2.ToList();
 var tmp3 = from index in Enumerable.Range(0,tmp1.Count-1)
       select new { tmp1[index] , tmp2[index] };

3.ToDictionary や ToLookup を使って連想配列を経由するとさらに色々な事が簡単に
4.他にも色々便利なコンテナもあるので To○○ を拡張を沢山作っておくのがコツ
 標準で .Net Framework に準備して欲しい・・・

260:1
08/10/27 22:22:05
ありそうで実は無くて意外不便なもの

1.Excelを使うと良く登場するパータンで、前後の要素にアクセスしながら新しい列を作るような手段が実はない
 [ ][0]
 [3][=A2]
 [4][=B2+A3]
 [6][=B3+A4]
 [2][=B4+A5]
 [5][=B5+A6]
 左の列を元に、右の列のようなシーケンスを作る関数を作っておくと便利、汎用関数も簡単につくれる。
 これなかった頃よく似た関数をあたりにぶちまけてしまった .Net Framework に準備して欲しい・・・

2.ツリー構造の全要素列挙、汎用関数も簡単につくれる。
 これなかった頃よく似た関数をあたりにぶちまけてしまった .Net Framework に準備して欲しい・・・

3.コントロールブレイク(コボラーの必殺技)も作っておくと便利。
 COBOLは実は触ったことが一度もないのですが、どうも色々便利ノウハウが彼らにはあるようです。
 現在鋭意開拓中

261:デフォルトの名無しさん
08/10/27 22:22:31
Enumerableにある関数は、全部使い込みましょう、特に重要なのは

シーケンスを混ぜて一つのシーケンスを作る系
 Enumerable.Concat()
 Enumerable.Intersect()
 Enumerable.Union()
 Enumerable.Except()

シーケンスの先頭や部分を取得する系
 Enumerable.First()
 Enumerable.FirstOrDefault()
 Enumerable.Take()
 Enumerable.Skip()

全シーケンスのチェック、これ以上複雑な物は foreach の方がかえって分かりやすい気がする。
 Enumerable.All()
 Enumerable.Any()
 Enumerable.SequenceEqual()

要素の型変換、指定型のみ抽出
 Enumerable.Cast()
 Enumerable.OfType()

マニュアルが余りに理解不能な文書なので、動作を確かめながら自分の言葉で整理しておくと便利です。
生成用関数、加工用関数、結果生成用関数の三つに分類してみると、すっきりしてきます。

262:デフォルトの名無しさん
08/10/27 23:24:32
サンプル通りにやってもAddの定義が無いのですが‥‥
URLリンク(www.atmarkit.co.jp)
ぶっちゃけ、この常連しんさんと全く同じ質問なのですが、
この人、質問して、自己解決して、回答書いてないので‥‥

263:デフォルトの名無しさん
08/10/27 23:38:24
関数型プログラム言語触れば別に驚くことでもない

264:デフォルトの名無しさん
08/10/28 01:43:36
Firstも使うけどSingleもよく使う

265:デフォルトの名無しさん
08/10/28 03:14:06
>>261
最も基本の Select, SelectMany が抜けてる

>>262
多分、LINQ to SQLだよな
Add がどこから出てきたのか知らんが、対象がTable<T>なら
データ操作にはInsert~とかDelete~あたりをつかう


266:262
08/10/28 13:58:59
>>265
どうもありがとうございます。>>262のサイトからさらっと試し始めたので‥‥
InsertOnSubmitを使うんだと分りました。
たぶん、あのサイトは記述が古いんですね。
とっても面白いので、本でも買って真面目に勉強します‥‥

267:デフォルトの名無しさん
08/10/28 17:52:37
>>265
基本といえば Where もないね

クエリ式で書けるものは入れてないのかな?

268:デフォルトの名無しさん
08/10/31 16:20:09
これってORマッピングツールみたいなものか?

269:デフォルトの名無しさん
08/10/31 19:53:08
>>267
ラムダで書くと見た目が不必要に複雑になるからな

270:デフォルトの名無しさん
08/10/31 19:59:39
C#の方は XML to LINQ を無理やりC#構文で書かせるのはなんとかしてほしい。
データ操作まで無理やりオブジェクト指向にするとかえって記述がグダグダになるんだよ。
データ操作は特化した記述がいい。

271:デフォルトの名無しさん
08/10/31 20:27:08
同じ記述でXMLが扱える所が利点なのに?
わざわざ特化した記述作って、新しく覚えないといけなかったら魅力感じないな

272:デフォルトの名無しさん
08/10/31 20:35:02
もしかして関数型構築のこと?

273:デフォルトの名無しさん
08/10/31 22:23:22
>>269
全部クエリ式で書けない場合は,joinとかletとか使わない限りは全部拡張メソッドで俺は書いちゃうな

274:デフォルトの名無しさん
08/11/01 02:17:30
クエリ式みたいなものを自由に拡張できるようにして欲しいお(´・ω・`)

275:デフォルトの名無しさん
08/11/01 02:29:34
そんなことしたらカオスになるじゃないか


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch