2009-10-07 76 views
2

我有一个查询返回10000个用作地图上绘图点的记录。为了减少负载并提高应用速度,我们试图实现逻辑基本相当于Level of Detail的操作。基本上,当缩小时,显示50%的点数。放大时,显示100%的点数。用LINQ返回每隔一个记录

这最终是什么,我需要最终的SQL看起来像:

SELECT * 
FROM 
    (SELECT 
     [t0].[RecordName], 
     [t0].[LastMaintenanceDate] 
     ,Row_Number() OVER (ORDER BY [t0].Ticker) as RowNumber 
     FROM 
      [dbo].[TableName] AS [t0] 
    )as [t1] 
WHERE RowNumber % 2 = 0 

在LINQ我可以使用.Skip和。取得到ROW_NUMBER()在部分(example here),但是这样做的时候,Where标准生成使用'between'而不是'where RowNumber%2 = 0',我需要。

我是否正确接近?为了获得我们在这里寻找的全部性能收益,这种排除实际上需要发生在SQL服务器上。

+0

这是一个非常有趣的问题,不幸的是我不知道使用纯LINQ to SQL的答案。我可以建议的唯一的事情是,LINQ to SQL *支持即席[原始SQL查询](http://msdn.microsoft.com/zh-cn/library/bb399403.aspx)。你的问题可能是这样做的有效案例。 – Randolpho 2009-10-07 20:23:50

回答

2

你在桌上有什么专栏?比如你有一个INT标识主键列,你可以使用...

from mt in dc.MyTable 
where mt.ID %2 == 0 
select mt 

......或者......

where mt.SomeDataTime.Millisecond % 2 == 0 

...这么说,其中你试图减少负荷?

您的文章中的T-SQL以及我提到的两个解决方案都将强制执行全表扫描,因此如果您的表是大型的,那么它会更好,您可以根据索引的内容减少记录where where子句谓词实际上可以使用索引)...

+0

我确实有一个ID类型的列,我可以使用这个逻辑,所以“where mt.Ticker%2 == 0”对我所要做的事情完美地工作。我显然需要更多地了解%运算符以及它的工作原理。我从来没有使用过,直到昨天,我发现它在我发布的示例链接。再次感谢!! – 2009-10-08 13:14:54

+0

顺便说一句,有关全表扫描的评论也很有帮助。幸运的是,在这种情况下,索引有问题的列不应该成为问题。 – 2009-10-08 13:16:03

+0

这是一个好主意,前提是结果在每隔一行之前不会被过滤。然而,添加任何类型的过滤器,分配将会改变。您可能不会均匀地跳过行,并且不太可能(取决于过滤器创建的最终分布)您将行数减半。只是警告你。如果要在跳过其他每行之前过滤结果,则需要使用存储过程。 – Randolpho 2009-10-08 13:49:44

0

morelinq项目有一个TakeEvery函数可以做到这一点,但这只适用于IEnumerable。

应该可以创建一个扩展方法来解决这个问题(我目前没有我的开发环境,所以我现在不能测试它)。

在你的具体例子中,我猜测表扩展方法就足够了。

如果你想尝试这个,有一个'例子'的表here表扩展方法。