我正在使用LINQ-to-Entities,并希望执行一个支点。
例如,我有这张表:
| data1 | data2 |
+-------+-------+
| 1 | A |
| 1 | B |
| 2 | P |
| 2 | Q |
| 2 | R |
+---------------+
我想将其转换为以下结果:
| data1 | first | second | third |
+-------+-------+--------+-------+
| 1 | A | B | NULL |
| 2 | P | Q | R |
+--------------------------------+
我想在LINQ中执行此操作,而无需进行客户端处理。
我看过这些SO帖子,但他们并没有完全解决上述情况(据我所知)。
注意
我已经尝试了下面的内容,但它抱怨我无法在无序集合上使用Skip(),并且我没有看到一种方法来对该组的折叠'data2'信息进行排序。
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,
};
答案 0 :(得分: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,
};
生成的相应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]
答案 1 :(得分:0)
我假设您可以在data2
字段中包含三列以上的内容?
如果是这样,则无法进行查询,返回具有可变数量属性的匿名类型。您需要为data2
值集返回一个数组或某种列表。
我认为这是你可以做的事情:
var query =
from mt in MyTable
group mt.data2 by mt.data1 into gmts
let d2 = gmts.ToArray()
select new
{
data1 = gmts.Key,
data2 = d2,
length = d2.Length,
};
var pending = query.ToArray();
var maxLength = pending.Max(p => p.length);
Func<string[], string[]> extend = xs =>
{
var r = new string[maxLength];
xs.CopyTo(r, 0);
return r;
};
var results =
from p in pending
select new
{
p.data1,
data2 = extend(p.data2),
};
这会产生一系列匿名类型,data2
数组的大小都相同,以适应任何data1
字段的最大结果数。
查询仍然作为单个SQL查询执行。而内存处理速度很快。
这对你有用吗?
修改强>
由于您知道自己拥有固定数量的列(根据评论),因此您可以轻松更改我的results
查询以满足您的要求:
var results =
from p in pending
let d2s = extend(p.data2)
select new
{
p.data1,
first = d2s[0],
second = d2s[1],
third = d2s[2],
};