1

私はEF5を使用しており、次のような質問を見つけています:

context.Questions
  .OrderBy(x => Guid.NewGuid())
  .Where(x => x.Difficulty == difficulty && x.Format == format);

各質問には、分単位の値 (2、4、6、および 8) を持つ期間という名前のフィールドがあります。

次の int 配列があります: { 4, 0, 1, 2 } つまり:

2 分の 4 問、4 分の 0 問、6 分の 1 問、8 分の 2 問を取得します。

.OrderBy と .Where の後、前述の 7 つの質問を取得する必要があります。

すべての質問をロードしたり、4 つのクエリを使用したりせずにこれを行う方法はありますか?

ありがとう、ミゲル

4

3 に答える 3

1

これは一種のハードコーディングされていますが、アイデアが得られ、問題が明示的に解決されます。ここから必要なものに変換できるはずです。

var questions =  context.Questions .OrderBy(x => Guid.NewGuid())
                        .Where(x => x.Difficulty == difficulty && x.Format == format);

var selectedQuestions = questions.Where(q => q.Duration == 2).Take(questionArray[0])
    .Union(questions.Where(q => q.Duration == 4).Take(questionArray[1]))
    .Union(questions.Where(q => q.Duration == 6).Take(questionArray[2]))
    .Union(questions.Where(q => q.Duration == 8).Take(questionArray[3]));

クエリ可能なものを列挙することはないため、EF はこれらすべてのユニオンを sql で実行し、1 回の呼び出しですべてのデータを取得します。

生成された SQL:

SELECT [Distinct3].[C1] AS [C1],
       [Distinct3].[C2] AS [C2],
       [Distinct3].[C3] AS [C3],
       [Distinct3].[C4] AS [C4]
FROM   (SELECT DISTINCT [UnionAll3].[C1] AS [C1],
                        [UnionAll3].[C2] AS [C2],
                        [UnionAll3].[C3] AS [C3],
                        [UnionAll3].[C4] AS [C4]
        FROM   (SELECT   [Distinct2].[C1] AS [C1],
                         [Distinct2].[C2] AS [C2],
                         [Distinct2].[C3] AS [C3],
                         [Distinct2].[C4] AS [C4]
                FROM     (SELECT DISTINCT [UnionAll2].[C1] AS [C1],
                                          [UnionAll2].[C2] AS [C2],
                                          [UnionAll2].[C3] AS [C3],
                                          [UnionAll2].[C4] AS [C4]
                          FROM   (SELECT   [Distinct1].[C1] AS [C1],
                                           [Distinct1].[C2] AS [C2],
                                           [Distinct1].[C3] AS [C3],
                                           [Distinct1].[C4] AS [C4]
                                  FROM     (SELECT DISTINCT [UnionAll1].[Id] AS [C1],
                                                            [UnionAll1].[Duration] AS [C2],
                                                            [UnionAll1].[Difficulty] AS [C3],
                                                            [UnionAll1].[Format] AS [C4]
                                            FROM   (SELECT   TOP (4) [Project1].[Id] AS [Id],
                                                                     [Project1].[Duration] AS [Duration],
                                                                     [Project1].[Difficulty] AS [Difficulty],
                                                                     [Project1].[Format] AS [Format]
                                                    FROM     (SELECT NEWID() AS [C1],
                                                                     [Extent1].[Id] AS [Id],
                                                                     [Extent1].[Duration] AS [Duration],
                                                                     [Extent1].[Difficulty] AS [Difficulty],
                                                                     [Extent1].[Format] AS [Format]
                                                              FROM   [dbo].[Questions] AS [Extent1]
                                                              WHERE  ([Extent1].[Difficulty] = @p__linq__0)
                                                                     AND ([Extent1].[Format] = @p__linq__1)
                                                                     AND (2 = [Extent1].[Duration])) AS [Project1]
                                                    ORDER BY [Project1].[C1] ASC
                                                    UNION ALL
                                                    SELECT   TOP (0) [Project3].[Id] AS [Id],
                                                                     [Project3].[Duration] AS [Duration],
                                                                     [Project3].[Difficulty] AS [Difficulty],
                                                                     [Project3].[Format] AS [Format]
                                                    FROM     (SELECT NEWID() AS [C1],
                                                                     [Extent2].[Id] AS [Id],
                                                                     [Extent2].[Duration] AS [Duration],
                                                                     [Extent2].[Difficulty] AS [Difficulty],
                                                                     [Extent2].[Format] AS [Format]
                                                              FROM   [dbo].[Questions] AS [Extent2]
                                                              WHERE  ([Extent2].[Difficulty] = @p__linq__2)
                                                                     AND ([Extent2].[Format] = @p__linq__3)
                                                                     AND (4 = [Extent2].[Duration])) AS [Project3]
                                                    ORDER BY [Project3].[C1] ASC) AS [UnionAll1]) AS [Distinct1]
                                  UNION ALL
                                  SELECT   TOP (1) [Project7].[Id] AS [Id],
                                                   [Project7].[Duration] AS [Duration],
                                                   [Project7].[Difficulty] AS [Difficulty],
                                                   [Project7].[Format] AS [Format]
                                  FROM     (SELECT NEWID() AS [C1],
                                                   [Extent3].[Id] AS [Id],
                                                   [Extent3].[Duration] AS [Duration],
                                                   [Extent3].[Difficulty] AS [Difficulty],
                                                   [Extent3].[Format] AS [Format]
                                            FROM   [dbo].[Questions] AS [Extent3]
                                            WHERE  ([Extent3].[Difficulty] = @p__linq__4)
                                                   AND ([Extent3].[Format] = @p__linq__5)
                                                   AND (6 = [Extent3].[Duration])) AS [Project7]
                                  ORDER BY [Project7].[C1] ASC) AS [UnionAll2]) AS [Distinct2]
                UNION ALL
                SELECT   TOP (2) [Project11].[Id] AS [Id],
                                 [Project11].[Duration] AS [Duration],
                                 [Project11].[Difficulty] AS [Difficulty],
                                 [Project11].[Format] AS [Format]
                FROM     (SELECT NEWID() AS [C1],
                                 [Extent4].[Id] AS [Id],
                                 [Extent4].[Duration] AS [Duration],
                                 [Extent4].[Difficulty] AS [Difficulty],
                                 [Extent4].[Format] AS [Format]
                          FROM   [dbo].[Questions] AS [Extent4]
                          WHERE  ([Extent4].[Difficulty] = @p__linq__6)
                                 AND ([Extent4].[Format] = @p__linq__7)
                                 AND (8 = [Extent4].[Duration])) AS [Project11]
                ORDER BY [Project11].[C1] ASC) AS [UnionAll3]) AS [Distinct3];
于 2013-03-05T12:34:51.960 に答える
0

各タイプの 4 つ (または配列の最大数) の質問を取得し、クライアントでフィルタリングを実行しないのはなぜですか? 16 の結果があれば、安価なはずです。linq グループ化を使用して分単位でグループ化すると、簡単になります。ここでのもう 1 つの興味深い点は順序付けです... 4 つ以上の質問があり、選択するときに常にそれらを順序付けている場合、最初の 4 つだけの他の質問が表示されることはありますか?

于 2013-03-05T19:33:53.817 に答える