需要帮助创建一个linq选择

时间:2013-04-04 21:25:15

标签: sql linq tsql linq-to-sql stored-procedures

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

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

4 个答案:

答案 0 :(得分:1)

我现在不接近电脑,所以我不确定语法是否正确100%,但我相信你正在寻找这样的东西:

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

答案 1 :(得分:1)

可以使用Linq来做,但它可能比传统的for循环慢很多。一种方法是:

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

这会跳过任何与“上一个”项目具有相同Type和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

答案 2 :(得分:1)

您可以使用LINQ执行此操作,但我认为可能更容易使用“for(each)loop”路径......

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 }));

答案 3 :(得分:1)

你坚持使用LINQ吗?

添加PK身份 按PK命令 使用DataReader只计算更改 然后在更改计数达到最大值时停止。

如果您不在.NET环境中,那么使用游标也是如此。

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