8

私は単純なテーブルを持っています:

ID | 価値

私がこれを行うとき:

var sequence = from c in valuesVault.GetTable()
               select new {RandomIDX = Guid.NewGuid(), c.ID, c.Value};

射影の各要素は同じ GUID の値を持っています...射影の要素ごとに異なるランダム GUID 値を取得するにはどうすればよいですか?

編集

問題を明確にする。GetTable ()メソッドは単純にこれを呼び出します。

        return this.context.GetTable<T>();

ここで、this.contenxt は T 型の DataContext です。

繰り返しはいつものように行われ、特別なことは何もありません:

     foreach (var c in seq) 
     {
          Trace.WriteLine(c.RandomIDX + " " + c.Value);
     }

出力:

bf59c94e-119c-4eaf-a0d5-3bb91699b04d What is/was your mother's maiden name?
bf59c94e-119c-4eaf-a0d5-3bb91699b04d What was the last name of one of your high school English teachers?
bf59c94e-119c-4eaf-a0d5-3bb91699b04d In elementary school, what was your best friend's first and last name?

編集 2 ボックスの linq2Sql プロバイダーを使用します。その周りにいくつかの汎用ラッパーを作成しましたが、コード内の IQuaryable または IEnumerable 関数の方法を変更しません。

4

4 に答える 4

6

下は何valuesVault.GetTable()ですか?

おそらく、Linq 2 SQL などの Linq プロバイダーを使用しているはずです。

つまり、それvaluesVault.GetTable()は型IQueryableであり、クエリ全体がになることを意味します。

式は、定義されているがまだ実行されていないクエリです。

が反復処理されている場合sequence、Linq プロバイダーとその Linq プロバイダーを使用してクエリが実行されます。実行する必要がある手順の 1 つは、次の式を実行することですGuid.NewGuid()。ほとんどの Linq プロバイダーは、その式を基になるソースに渡すことができないため (SQL Server はそれをどう処理するかを認識しません)、一度実行され、実行の結果が残りの結果と共に返されます。

またはメソッドを呼び出して、valuesVault.GetTable()式を強制的にコレクションにすることができます。これは式を実行し、メモリ内コレクションを表すを返します。.ToList().ToArray()IEnumerable

に対してクエリを実行するIEnumerableと、実行は Linq プロバイダーに渡されず、.NET ランタイムによって実行されます。

あなたの場合、これは式Guid.NewGuid()を正しく実行できることを意味します。

これを試して:

var sequence = from c in valuesVault.GetTable().ToArray()
               select new {RandomIDX = Guid.NewGuid(), c.ID, c.Value};

そこにある.ToArray()に注目してください。それがステートメントを からIQueryableIEnumerable変更し、その動作を変更します。

于 2011-03-10T21:29:58.843 に答える
4

それがSQLに変換されたときに起こっていると思います(つまり、それを行うのはデータベースです)。この例には WHERE 句がないため、次のようにすることができます。

var sequence = from c in valuesVault.GetTable().ToList()
               select new { RandomID = Guid.NewGuid(), c.ID, c.Value };

これにより、 Guid.NewGuid() がクライアントで強制的に実行されます。ただし、テーブルが大きくなり、フィルタリング句を追加し始めると、見苦しくなります。新しい GUID を使用して 2 番目の結果セットを射影する 2 番目の LINQ クエリを使用することで、この問題を解決できます。

var sequence = from c in valuesVault.GetTable()
               where c.Value > 10
               select new { c.ID, c.Value };

var finalSequence = from s in sequence.ToList()
                    select new { RandomID = Guid.NewGuid(), s.ID, s.Value };
于 2011-03-10T21:31:51.017 に答える
2

私にはうまくいくようです。

List<int> a = new List<int> {10, 11, 12, 13};

            var v = a.Select(i => new {ID = Guid.NewGuid(), I = i});
            foreach (var item in v)
            {
                Console.WriteLine(item);
            }

出力

{ ID = b760f0c8-8dcc-458e-a924-4401ce02e04c, I = 10 }
{ ID = 2d4a0b17-54d3-4d69-8a5c-d2387e50f054, I = 11 }
{ ID = 906e1dc7-6de4-4f8d-b1cd-c129142a277a, I = 12 }
{ ID = 6a67ef6b-a7fe-4650-a8d7-4d2d3b77e761, I = 13 }
于 2011-03-10T21:31:53.973 に答える
1

単純な LINQ クエリでこの動作を再現することはできません。サンプル:

List<int> y = new List<int> { 0, 1, 2, 3, 4, 5 };

var result = y.Select(x => new { Guid = Guid.NewGuid(), Id = x }).ToList();

テーブルの値をLinqのリストに変換してから選択を実行すると、異なるGuidが得られると想像しています。

于 2011-03-10T21:31:47.050 に答える