2013-04-04 50 views
4

我需要一些帮助创建一个LINQ选择,我有一个表中有一些列,但只有2这个问题的兴趣。需要帮助创建一个LINQ选择

userid, type 

现在这个表有几千项,我只想要顶部,让我们说50到目前为止好,但最困难的部分是,有成功的一个很多行只应是计为1 例

Type UserId 
============ 
Add 1 
Add 1 
Add 1 
Add 2 

我想这行我取出的限制只能算作2,但我想仍有待被输出的所有的行。 这是可能的一个单一的SQL请求,或者我应该找到另一种方式来做到这一点?

编辑:我可以添加列到表中,如果这可以解决问题的值。 EDIT2:Sotred程序也是一种溶液

实施例2:此应该算作3行

Type UserId 
============ 
Add 1 
Add 1 
Add 2 
Add 1 
+2

我觉得这很难。 Linq和SQL擅长设置操作,而不是顺序处理。经典的'foreach'更适合这里。 – 2013-04-04 21:47:12

+0

是的,但我不想从数据库中获取更多的需要,理论上可以在那里有多于1000行的序列 – Androme 2013-04-04 21:48:51

+0

我看到一个存储过程迫在眉睫... – 2013-04-04 21:50:32

回答

1

你坚持使用LINQ吗?

添加一个PK身份。
按PK排序。
使用DataReader并只计算更改。
然后,只要停止当更改计数是在您的最大值。

如果你不在.NET环境中,那么与光标相同的东西。

由于LINQ被推迟,你可能只能在LINQ中订购,然后在ForEach上退出。

+0

我想坚持我的存储库,但这将适当地成为最好的解决方案。 – Androme 2013-04-04 23:02:14

+0

查看我的答案更新 – Paparazzi 2013-04-05 14:13:24

1

我不是接近计算机现在所以我不知道是100%正确的语法明智的,但我相信你正在寻找的东西是这样的:

data.Select(x => new {x.Type, x.UserId}) 
    .GroupBy(x => x.UserId) 
    .Take(50); 
+0

我还没有真正与groupby合作过很长一段时间,但是我记得它会将所有条目分组为1条单条目吗? – Androme 2013-04-04 21:35:19

+0

你是对的,我没有注意到其他条件,它应该只分组相邻,我会给它更多的思考解决方案,并回来编辑。 – 2013-04-04 22:58:02

1

可能使用LINQ做到这一点,但它可能是很多比传统for循环慢。一种方法是:

data.Where((s, i) => i == 0 || 
        !(s.Type == data[i-1].Type && s.UserId == data[i-1].UserId)) 

这将跳过任何“重复”项目具有相同类型和用户标识与“上一个”项目。

但是,只有data有一个索引器(一个数组或者实现了IList的东西)才能工作。 IEnumerableIQueryable将不起作用。另外,它几乎肯定不会被SQL翻译,因此您必须将所有结果都提取出来并过滤内存。

如果你想在SQL中完成它,我会尝试扫描游标并填充临时表,如果其中一个值发生变化或使用包含ROW_NUMBER列的公用表表达式,查询类似的LINQ上述方法:

WITH base AS 
(
SELECT 
    Type, 
    UserId, 
    ROW_NUMBER() OVER (ORDER BY ???) AS RowNum 
    FROM Table 
) 
SELECT b1.Type, b1.UserId 
FROM base b1 
LEFT JOIN base b2 ON b1.RowNum = b2.RowNum - 1 
WHERE (b1.Type <> b2.Type OR b1.UserId <> b2.UserId) 
ORDER BY b1.RowNum 
+0

这就是我想要避免的,理论上这张桌子可能会有更多的上千个条目! – Androme 2013-04-04 22:02:49

+0

嗯,我不能你所做的工作的SQL,但如果我正确地读它剂量它不仅返回不同的值? – Androme 2013-04-04 22:24:30

+0

它应该返回与下一行不同的任何行。最后一行应该被包含,因为那个时候'b2'值将是NULL。你是否收到错误或者错误的结果? – 2013-04-04 22:28:06

1

你可以用LINQ做到这一点,但我认为这可能是更容易去了“(每个)循环”路线......

data.Select((x, i) => new { x.Type, x.UserId, i }) 
    .GroupBy(x => x.Type) 
    .Select(g => new 
    { 
     Type = g.Key, 
     Items = g 
      .Select((x, j) => new { x.UserId, i = x.i - j }) 
    }) 
    .SelectMany(g => g.Select(x => new { g.Type, x.UserId, x.i })) 
    .GroupBy(x => new { x.Type, x.i }) 
    .Take(50); 
    .SelectMany(g => g.Select(x => new { x.Type, x.UserId }));