透过Linq

jwd*_*jwd 7 linq linq-to-entities pivot pivot-table sql-server-2008

我正在使用LINQ-to-Entities,并希望执行一个支点.

例如,我有这个表:

| data1 | data2 |
+-------+-------+
|   1   |   A   |
|   1   |   B   |
|   2   |   P   |
|   2   |   Q   |
|   2   |   R   |
+---------------+
Run Code Online (Sandbox Code Playgroud)

我想将其转换为以下结果:

| data1 | first | second | third |
+-------+-------+--------+-------+
|   1   |   A   |   B    | NULL  |
|   2   |   P   |   Q    |   R   |
+--------------------------------+
Run Code Online (Sandbox Code Playgroud)

我想在LINQ中执行此操作,而无需进行客户端处理.

我看过这些SO帖子,但是他们并没有完全解决上述情况(据我所知).



注意 我曾尝试以下,但它抱怨说,我不能在一个无序的集合使用跳过(),我没有看到一个办法让该集团的崩溃"数据2"信息进行排序.

from item in MyTable
group item by item.data1 into g
select new
{
    data1 = g.Key,
    first = g.Skip(0).FirstOrDefault().data2,
    second = g.Skip(1).FirstOrDefault().data2,
    third = g.Skip(2).FirstOrDefault().data2,
};
Run Code Online (Sandbox Code Playgroud)

jwd*_*jwd 0

嗯,这似乎有效,尽管我想知道它的效率如何。

from item in MyTable
group item by item.data1 into g
select new
{
    data1 = g.Key,
    first = g.OrderBy(x => x.data2).Skip(0).FirstOrDefault().data2,
    second = g.OrderBy(x => x.data2).Skip(1).FirstOrDefault().data2,
    third = g.OrderBy(x => x.data2).Skip(2).FirstOrDefault().data2,
};
Run Code Online (Sandbox Code Playgroud)

生成的相应 SQL(从 LINQPad)是:

SELECT [t1].[data1], (
    SELECT [t5].[data2]
    FROM (
        SELECT TOP (1) [t4].[data2]
        FROM (
            SELECT [t3].[data2], [t3].[ROW_NUMBER]
            FROM (
                SELECT ROW_NUMBER() OVER (ORDER BY [t2].[data2]) AS [ROW_NUMBER], [t2].[data2]
                FROM [MyTable] AS [t2]
                WHERE [t1].[data1] = [t2].[data1]
                ) AS [t3]
            WHERE [t3].[ROW_NUMBER] > @p0
            ) AS [t4]
        ORDER BY [t4].[ROW_NUMBER]
        ) AS [t5]
    ) AS [first], (
    SELECT [t10].[data2]
    FROM (
        SELECT TOP (1) [t9].[data2]
        FROM (
            SELECT [t8].[data2], [t8].[ROW_NUMBER]
            FROM (
                SELECT ROW_NUMBER() OVER (ORDER BY [t7].[data2]) AS [ROW_NUMBER], [t7].[data2]
                FROM (
                    SELECT [t6].[data2]
                    FROM [MyTable] AS [t6]
                    WHERE [t1].[data1] = [t6].[data1]
                    ) AS [t7]
                ) AS [t8]
            WHERE [t8].[ROW_NUMBER] > @p1
            ) AS [t9]
        ORDER BY [t9].[ROW_NUMBER]
        ) AS [t10]
    ) AS [second], (
    SELECT [t15].[data2]
    FROM (
        SELECT TOP (1) [t14].[data2]
        FROM (
            SELECT [t13].[data2], [t13].[ROW_NUMBER]
            FROM (
                SELECT ROW_NUMBER() OVER (ORDER BY [t12].[data2]) AS [ROW_NUMBER], [t12].[data2]
                FROM (
                    SELECT [t11].[data2]
                    FROM [MyTable] AS [t11]
                    WHERE [t1].[data1] = [t11].[data1]
                    ) AS [t12]
                ) AS [t13]
            WHERE [t13].[ROW_NUMBER] > @p2
            ) AS [t14]
        ORDER BY [t14].[ROW_NUMBER]
        ) AS [t15]
    ) AS [third]
FROM (
    SELECT [t0].[data1]
    FROM [MyTable] AS [t0]
    GROUP BY [t0].[data1]
    ) AS [t1]
Run Code Online (Sandbox Code Playgroud)