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

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

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

ちょっと使ってみると、意外と難しいし、テクニック的にも奥が深いものです。
関数型言語にしかないような機能ラムダ式(Lambda式)などはオブジェクト指向とは一味違う機能です。
DataBaseの操作にも、Xmlの操作にも、さらにもっと単純な配列なコンテナにさえ機能する
言語共通・高汎用な統合言語クエリを皆で一緒にマターリ勉強しましょう。
質問、便利なマイテクニックの発表、いろいろやっちゃってください。
2008/09/11(木) 20:45:39
りんきゅー><
2008/09/17(水) 20:13:37
↓をメソッド形式で書きたいのですが、OrderByメソッドで複数のプロパティで
ソートするのははどうすればいいですか?

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

OrderBy二回せずに一回でさくっと書きたいです。
2008/09/17(水) 22:32:24
>>222
OrderBy(1つ目の条件).ThenBy(2つ目の条件)

OrderBy 1回というのは無理。
2008/09/18(木) 20:14:01
>>223
ThenByって知らなかった。ありがと。
2008/09/19(金) 01:50:55
つか、そんなの条件式を二つ持つOrderByを自分で実装するがよろし
2008/09/19(金) 03:17:06
引数可変にしてOrderBy〜ThenByに丸投げで、1分とかからずに実装できるな
227デフォルトの名無しさん
垢版 |
2008/09/19(金) 07:24:56
こうして車輪は四角に変容しバグを抱擁した後に再輸出されるのであった...
228デフォルトの名無しさん
垢版 |
2008/09/28(日) 23:54:29
LINQの遅延実行と即時実行は正直いらない気がする。
Aggreegate戻り値はIntegerだし、クエリ機能あれば十分なのでは。

LINQ TO XMLとか開発の現場でまず使うのは小数だろうし、可用性が低いよ。
VBチームの自己満足だね。いつものことだけど。
2008/09/29(月) 12:49:16
>>228
VBのAggregate構文のことかEnumerable.Aggregateのことを言ってるのかわからない。
Integerってどういう意味だろう、集計対象の型で集計されると思うけど。

VBのLinqは使いやすくしようと、文法やキーワードを増やしすぎて
収集がつかなくなってるという感じはする。C#と同じにしておけば良かったような。
2008/09/29(月) 14:30:31
VBはラムダ式が冗長だから拡張メソッドでクエリ書くと悲惨なことになる
2008/09/29(月) 14:54:49
遅延実行と即時評価ってやたら強調されてるけど
やっぱりC#のyield知らないとわかりにくいのかな
2008/09/29(月) 23:02:22
言われてみるとyieldを知らない(あまり使った事がない)とすれば
即時実行でないのに違和感を感じるのも分かるな。
233デフォルトの名無しさん
垢版 |
2008/09/30(火) 11:58:27
いまさらだけど、yield Returnつう名前がややこすいよ!!
2008/09/30(火) 23:43:43
yield とかってどこからきたん?関数型?
2008/09/30(火) 23:47:50
Rubyのはクロージャ呼び出しだからPythonかなぁ。
Windows2x時代のAPIは関係ないと思う。
236デフォルトの名無しさん
垢版 |
2008/10/01(水) 02:17:48
ICONからきていると予想
Fiberはいつのまにか消えていたってオチかな
237[Fn]+[名無しさん]
垢版 |
2008/10/02(木) 00:00:54
てかDTDとかXMLスキーマサポートしてない段階でLINQ廃レは確定ぽ。。
2008/10/02(木) 00:06:53
それは LINQ to XML の問題であって、LINQ の問題じゃないのでは。
2008/10/02(木) 01:54:39
LINQ to XMLはもともとXmlDOMやXmlReaderの代替を狙ったものじゃなく、
standaloneのXMLや部分的なXMLを簡単に扱えることを目指したもの。
はじめからDTDやXMLSchemaはサポートしないことになっていた。
もっともnamespaceを中途半端なサポートはチトいただけないから改良は欲しい。
いっそなくすか、もっと充実させるかどちらかで。
2008/10/02(木) 08:21:03
スキーマはサポートしない、って確かにそうなんだけど
ぶっちゃけあれ下層に XmlReader が使えるからでは
ないのかと
241デフォルトの名無しさん
垢版 |
2008/10/02(木) 13:10:43
LINQはすんばらしい
FOR EACH書かなくてすむし、べた書きのXMLもコードとして扱える。
2008/10/03(金) 00:46:47
C#だとエディットコンティニューが使えないのは結構痛い
2008/10/03(金) 10:10:47
エディットコンティニュかあ、x64だと使えないんだよなあ。
まあx86にすりゃいいんだけど、デフォがAnyCPUだからなあ。
244デフォルトの名無しさん
垢版 |
2008/10/11(土) 23:59:11
てかLINQってORACLEとかポスグレでも使えるのね。
2008/10/12(日) 00:58:14
>>244
LINQ to Entity の出た今となってはね。
MS SQL Server でしか使えないって言われてたのは、
SP1 入る前、LINQ to SQL の時代の話。
2008/10/12(日) 02:57:11
別に Linq to SQL でも別データベースサポート可能だよ。
でも Linq -> Entity SQL がサポートされたから、Entity SQL ->
ネイティブ SQL だけでいいじゃん=皆やる気ナスなだけで。
247デフォルトの名無しさん
垢版 |
2008/10/12(日) 20:47:40
Linq to Entityが生成する生のSQLを確認する方法を教えてください。
2008/10/13(月) 00:46:17
それは実行される前に?恒常的に?
そうじゃないならログ見りゃいいと思うけど・・・
2008/10/13(月) 17:15:00
>>248
実行時でかまいません。
Linq to SQLのようのDataContext.Logプロパティにあたるものが見当たらないようです。
またSystem.DiagnosticsのTraceやDebugでも確認できませんでした。
探し方が悪いのかもしれませんがSQLのログを出力する方法を教えてください。
2008/10/13(月) 21:39:14
だから SQL Server なら確かプロファイラ起動してトレースの開始で…
と記憶を頼りにぐぐって気づいたんだが Express にはないのか
このツール。おおう。それとごめんトレースだった

2005 ならこんなの見つけたけど
ttp://code.google.com/p/sqlexpressprofiler/
2008/10/17(金) 03:19:46
タイプセーフなデータベースプログラミング
ttp://d.hatena.ne.jp/higayasuo/20081014/1223969275

拡張メソッドとラムダ式と式木と匿名型とvarとあって良かったと思える瞬間。
2008/10/17(金) 17:46:42
Entity FrameworkをLinqなしで使うと2番目の例っぽくなるね。
2008/10/17(金) 19:35:37
多言語でLinqのパクリを作ろうと思っても、言語仕様のサポートが無いと
ああいう風にせざるをえないんだよな。
2008/10/17(金) 22:35:24
まあ、だからC# 3.0がああなったわけで。
2008/10/17(金) 22:53:01
その辺Booなら自分で言語使用作れるかと
2008/10/18(土) 10:13:17
実際に動くものを作ってから言え
257デフォルトの名無しさん
垢版 |
2008/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 が真の力を発揮するのはデータベースではなく、日常的に使う配列やオブジェクトです。
いままではデータベースではクエリで簡単に実行できても、プログラム中ではできずと
やむなくデータベースに一旦突っ込んでやるか、フルスクラッチで同等機能を作り出すかと、
無意味なプログラム実行環境の大規模化を引き起こしていました、これが無くなります。
2581
垢版 |
2008/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 に準備して欲しい・・・
2591
垢版 |
2008/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 に準備して欲しい・・・
2601
垢版 |
2008/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デフォルトの名無しさん
垢版 |
2008/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デフォルトの名無しさん
垢版 |
2008/10/27(月) 23:24:32
サンプル通りにやってもAddの定義が無いのですが‥‥
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=46703&forum=7&2
ぶっちゃけ、この常連しんさんと全く同じ質問なのですが、
この人、質問して、自己解決して、回答書いてないので‥‥
263デフォルトの名無しさん
垢版 |
2008/10/27(月) 23:38:24
関数型プログラム言語触れば別に驚くことでもない
2008/10/28(火) 01:43:36
Firstも使うけどSingleもよく使う
2008/10/28(火) 03:14:06
>>261
最も基本の Select, SelectMany が抜けてる

>>262
多分、LINQ to SQLだよな
Add がどこから出てきたのか知らんが、対象がTable<T>なら
データ操作にはInsert〜とかDelete〜あたりをつかう
266262
垢版 |
2008/10/28(火) 13:58:59
>>265
どうもありがとうございます。>>262のサイトからさらっと試し始めたので‥‥
InsertOnSubmitを使うんだと分りました。
たぶん、あのサイトは記述が古いんですね。
とっても面白いので、本でも買って真面目に勉強します‥‥
2008/10/28(火) 17:52:37
>>265
基本といえば Where もないね

クエリ式で書けるものは入れてないのかな?
268デフォルトの名無しさん
垢版 |
2008/10/31(金) 16:20:09
これってORマッピングツールみたいなものか?
2008/10/31(金) 19:53:08
>>267
ラムダで書くと見た目が不必要に複雑になるからな
2008/10/31(金) 19:59:39
C#の方は XML to LINQ を無理やりC#構文で書かせるのはなんとかしてほしい。
データ操作まで無理やりオブジェクト指向にするとかえって記述がグダグダになるんだよ。
データ操作は特化した記述がいい。
2008/10/31(金) 20:27:08
同じ記述でXMLが扱える所が利点なのに?
わざわざ特化した記述作って、新しく覚えないといけなかったら魅力感じないな
2008/10/31(金) 20:35:02
もしかして関数型構築のこと?
2008/10/31(金) 22:23:22
>>269
全部クエリ式で書けない場合は,joinとかletとか使わない限りは全部拡張メソッドで俺は書いちゃうな
2008/11/01(土) 02:17:30
クエリ式みたいなものを自由に拡張できるようにして欲しいお(´・ω・`)
2008/11/01(土) 02:29:34
そんなことしたらカオスになるじゃないか
2008/11/01(土) 09:41:51
クエリ式は抽象化の度合いを下げないまま、
foreachをネストさせた時の様に変数を扱えるのが便利だね。

これを拡張可能にすると・・・関数型っぽくなる気がする。
2008/11/01(土) 09:50:56
>>275
しかしそれがいい・
>>276
調子に乗ってクエリ式つなげてくと遅くなるらしいからなぁ・・・
記述方法は大好きなんだが。
2008/11/01(土) 10:45:55
>>277
遅くなるってのは意外と平気。
かなりバカに書かない限りはforeach書くのと比べて1割くらいしかパフォーマンス落ちない。
2008/11/01(土) 11:38:48
遅延評価を繋げるだけならほとんど遅くはならないはず
2008/11/01(土) 11:49:52
遅い速いは相対的なものだからどのレベルで遅いといってるのか示さないと議論にならない。
非常に細かいパフォーマンスを気にしているなら、
ラムダ式(デリゲート)を使うので関数の呼び出しがインライン化されないとか、
SumやMaxなど集計系メソッドを複数使った場合にちょっと効率の悪いことをしているとか
そんなところだね。
2008/11/01(土) 12:18:38
Reverseってバッファ使うから即時実行だと思ってたんだけど、Reverseの呼び出し時じゃなくて
最初のMoveNextの呼び出しの時点ですべての結果が決まるから遅延実行になるのか
速い遅い気にするならどういう実装になってるか気にしないといけないね
2008/11/01(土) 12:31:55
3.0出始めの時に誰かが、foreachで条件とか変換とか並べて書いたのと、クエリ式とか並べて頴田の比べて結構違いがあったような。
2008/11/01(土) 12:37:47
Linq to ObjectとLinq to SQLは分けないと話が食い違うから要注意。
2008/11/01(土) 12:44:36
この文脈でどう読んだらto SQLになるのか
2008/11/01(土) 12:50:21
4.0の紹介ビデオみてるが、よいなぁこれ・・・
来年早々にも出してくれんかな・・・
2008/11/01(土) 13:11:04
PLINQとか並列化関係いいなぁ・・
2008/11/05(水) 00:04:48
4.0の紹介ビデオってmsdnにある?
2008/11/05(水) 00:12:26
http://channel9.msdn.com/pdc2008/TL16/

ちなみに、パスを1段削って、
http://channel9.msdn.com/pdc2008/
にするとPDCのセッションの一覧が出てくる。
2008/11/05(水) 00:31:16
thx
2008/11/06(木) 01:31:48
C#インタプリタ、すげぇ!
2008/11/06(木) 09:38:50
>>282
http://ufcpp.net/study/csharp/sp3_linqreconstruct.html#iterator
これ?

foreach で置き換えるだけじゃたいして性能変わらない。
ここで違いが出てるのはそれの次の節の話で、
「if をループの外に出せ」と同じ原理で
「可能な限り where を from の上に」ってやるとパフォーマンス結構変わる。
2008/11/06(木) 10:16:15
LINQのクエリ式とSQLの一番の違いがプランナの有無。
クエリ式は書いた順番どおりに処理していくが、
SQLはプランナが最適な実行計画を立てる。
2008/11/06(木) 10:39:15
LinqtoObjectも気合い入れてプロバイダ書けばプランナ相当のもの記述可能?
いや書く気毛頭無いですが
2008/11/08(土) 12:26:24
やろうとおもえばLINQでスクリプト言語書けるよ
2008/11/09(日) 21:52:31
>> 294
出だしだけでもKWSK
2008/11/11(火) 17:07:42
LINQ to SQLって無くなるの?
なんつーか、ぶちまければ良いってもんじゃねぇだろ。
そんなのはオプソ系に任せとけよ。
2008/11/11(火) 18:08:39
何で無くなると思ったのさ?
2008/11/11(火) 18:35:18
なくなるっつーかLinq to Entityに置き換えでしょ。
別に今のところは対して書き方が違うわけじゃないし
Linq to Entity完成までの代打的存在として十分用を果たしたような。
2008/11/11(火) 22:44:48
うむ。かなりの部分でSQLの開発楽にしてくれた。
ストーリーにちゃんと沿わないと痛い目あうがなwww
2008/11/11(火) 23:18:07
>>296
開発が止まるだけで今後も当面は.NET Frameworkに標準搭載が続くんじゃないの?
2008/11/12(水) 00:12:05
Entity Frameworkは絶対こける。
間違いない。
2008/11/12(水) 00:44:11
>>301
まあVer.3ぐらいになるまでは毎回大変更の嵐だろうな。
2008/11/12(水) 17:23:24
Entity FrameworkはLinq to SQLの問題点が色々と解決されてるんだけど
デザイナが使いにくすぎる。

RailsのActiveRecordみたいに
ちょこちょこっとクラスに属性を付ければモデル完成、
ってのフレームワークだったらよかったのに。
304デフォルトの名無しさん
垢版 |
2008/11/20(木) 12:30:10
LINQ to SQLってADO.NETより目茶苦茶いいな。
更新系では、生のSQL文に完全なWHERE句を入れてくれるし、
非接続型・楽観的制御(←赤間さん流)では文句なし。
あと、生SQLのサブクエリ相当の組み合わせを段階を踏んで書けるのもいい。
デバッグも迅速になりそう。
2008/11/20(木) 15:06:45
俺、LINQ to P2P で当てたら結婚すんだ。
2008/11/20(木) 21:51:19
>>304
消える運命にあるが
2008/11/20(木) 22:15:10
なんらかの形で残るよ。使ってみれば、この方向性で進化していくんだろうと判る。
今のはちょっとSQL Serverに特化しすぎてるからディスコンかもしれないけどさ。
2008/11/20(木) 22:16:56
>>307
この方向性で進化した結果がLinq to Entityなんだけど、今のところいまいちの出来。
2008/11/20(木) 22:32:43
>>308
Entity Framework自体まだ手を付けてないのだが、どういまいち?
310デフォルトの名無しさん
垢版 |
2009/01/04(日) 23:25:17
例えば、
Select Sum(col1),Sum(col2),Sum(col3) from Table1
なSQLだとLINQではどう書くの?
311デフォルトの名無しさん
垢版 |
2009/01/04(日) 23:46:52
>>310
そんな質問はつい最近掲示板で見た事あるな
2009/01/04(日) 23:59:48
これか。ググったら一発で出てきたw
ttp://bbs.wankuma.com/index.cgi?mode=all&namber=30713
2009/01/05(月) 00:53:25
ただのマルチじゃねーかw
314デフォルトの名無しさん
垢版 |
2009/01/07(水) 02:50:59
>>311 >>312 >>313
ケチは付けられても結局答えられる奴いねぇんだな
暇なカス野郎だけかよ
2009/01/07(水) 03:06:42
var result =
from item in Table1
select new {Sum1 = item.col1.Sum(), Sum2 = item.col2.Sum(), Sum3 = item.col3.Sum(), }

でいいんじゃね?
2009/01/07(水) 04:16:09
いや、良くない。範囲変数itemは単なる1レコードで、item.col?はスカラー
1回のループで計算したいなら、アキュムレータ使うしかないはず

var sum = Table1.Aggregate(new[] { 0, 0, 0 }, (y, x) => {
  y[0] += x.col1;
  y[1] += x.col2;
  y[2] += x.col3;
  return y;
});
2009/01/07(水) 05:35:25
>>316
それはクエリプロバイダ次第じゃなかろうか。

確かにLINQ to Objectのみなら>>316の書き方の方が速い。

しかしTable1.Aggregateのオーバーロード解決次第によっては
クエリプロバイダの提供する最適なクエリ演算子ではなく
LINQ to Objectの低速なパスで実行されるため>>316はかえって遅くなる。

式木的に
Select Sum(col1),Sum(col2),Sum(col3) from Table1
というSQLに対応するのが何かと聞かれれば>>315を推したい。

あとは>>310が何を期待して聞いたか次第かな。
LINQ to SQLでの書き方を期待していたなら>>315でも最適化されたと思うが。
2009/01/07(水) 08:09:53
LINQ to SQL、生成されたSQLクエリがどんなのか見れるから試してみればいいんでは。
2009/01/07(水) 08:21:29
いつもながらLinq to ほにゃららを明記しないと話がこじれるな。
Linq to Entityかもしれない。
2009/01/07(水) 10:45:44
マルチに答えるとつけあがるからやめとけ
2009/01/07(水) 12:34:27
>>317
考え方はいいとして、>>315のコードが間違っているのは無視か

var sum1 = Table1.Sum(item => item.col1);
var sum2 = Table1.Sum(item => item.col2);
var sum3 = Table1.Sum(item => item.col3);

やるならこうだろ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況