LINQPadに付属するlinqサンプルのいくつかを驚いていました。 Chater 9 - Groupingの下にある "C#3.0 in a Nutshell"フォルダには、 "Multiple Keys Grouping"というサンプルクエリがあります。これは、以下のクエリが含まれていますVB.NET linq group by匿名の型が期待どおりに機能しない
from n in new[] { "Tom", "Dick", "Harry", "Mary", "Jay" }.AsQueryable()
group n by new
{
FirstLetter = n[0],
Length = n.Length
}
私は、実際のグループ化を取得するために、配列の末尾に文字列「ジョン」を追加し、以下の結果を思い付いた:
このまさに私が期待していたものでした。一緒にしないの適切グループジェイ/ジョン
' Manually added "Jon"
from n in new string() { "Tom", "Dick", "Harry", "Mary", "Jay", "Jon" }.AsQueryable() _
group by ng = new with _
{ _
.FirstLetter = n(0), _
.Length = n.Length _
} into group
結果を:次に、LINQPadに、私は同じクエリのVB.NET版に行ってきました。
ビットのために私の髪を引っ張った後、私はVB.NET匿名型を議論this MSDN articleを発見しました。 VB.NETでは、デフォルトで変更可能ですが、C#では不変です。 VBでは、Key
キーワードを追加して不変にする必要があります。だから、私は(Key
のほかに気づく)これにクエリを変更:
-
:だから私の質問はこれです
- linqが等価比較を行うときに、匿名型の可変性/不変性が問題になるのはなぜですか?特に、Linq-to-SQLでは、それはまったく重要ではありません。これはおそらくSQLへの翻訳の単なる製品です。しかし、Linqからオブジェクトへは、明らかにすべての違いがあります。
- なぜMSはVBの匿名型を変更可能にするのですか?私は本当の利点はないと思っています。そして、この問題をぶち壊した後、私はいくつかの本当の欠点を見ます。つまり、linqのクエリに微妙なバグがある可能性があります。
:
from n in new string() { "Tom", "Dick", "Harry", "Mary", "Jay", "Jon" }.AsQueryable() _
group by ng = new with _
{ _
Key .FirstLetter = n(0), _
Key .Length = n.Length _
} into group
これは私に正しい結果を与えました
- EDIT -
情報のジャスト面白い余分な部分...どうやらこれは鍵付きプロパティの問題では広く知られています。私はちょうどGoogleに何を知らなかった。 stackoverflowでhereとhereが議論されています。ここでは匿名型と個別を使用して、問題の別の例です:
Dim items = New String() {"a", "b", "b", "c", "c", "c"}
Dim result = items.Select(Function(x) New With {.MyValue = x}).Distinct()
Dim result2 = items.Select(Function(x) New With {Key .MyValue = x}).Distinct()
'Debug.Assert(result.Count() = 3) ' Nope... it's 6!
Debug.Assert(result2.Count() = 3)
ありがとうございました!私はこの問題を1年以上にわたって解決してきました。この奇妙な問題を解決するために、すべてのグループ化コードが荒廃しています。私はちょうどこの問題を示すためにサンプルをノックし、治療法を見つけようとしましたが、これは解決策のようです。 「Key」キーワードを追加することが解決策です。私はpastebinのコードをここに入れました:http://pastebin.com/pa7KjZv2 – Tom