Linq-to-SQL:对连续元素的算术运算

时间:2015-01-10 18:03:58

标签: c# sql-server-2008 linq-to-sql

例如,我有一张桌子:

Date      |Value
----------|-----
2015/10/01|5
2015/09/01|8
2015/08/01|10

有没有办法使用Linq-to-SQL来获取一个新序列,这个序列将是先前有序集合中连续元素之间的算术运算(例如,i.Value - (i-1).Value)?它必须在SQL Server 2008端执行,而不是在应用程序端执行。

例如dataContext.GetTable<X>().OrderByDescending(d => d.Date).Something(.......).ToArray();应该返回3, 2

有可能吗?

2 个答案:

答案 0 :(得分:1)

你可以试试这个:

var q = (
         from i in Items
         orderby i.ItemDate descending
         let prev = Items.Where(x => x.ItemDate < i.ItemDate).FirstOrDefault()
         select new { Value = i.ItemValue - (prev == null ? 0 : prev.ItemValue) }
        ).ToArray();

修改

如果您稍微将上述linq查询修改为:

var q = (from i in Items
         orderby i.ItemDate descending
         let prev = Items.Where(x => x.ItemDate < i.ItemDate).FirstOrDefault()
         select new { Value = (int?)i.ItemValue - prev.ItemValue }
        ).ToArray();

然后您将以下TSQL查询发送到数据库:

SELECT ([t0].[ItemValue]) - ((SELECT [t2].[ItemValue]
                              FROM (SELECT TOP (1) [t1].[ItemValue]
                                    FROM [Items] AS [t1]
                                    WHERE [t1].[ItemDate] < [t0].[ItemDate]) AS [t2]
                              )) AS [Value]
FROM [Items] AS [t0]
ORDER BY [t0].[ItemDate] DESC

我现在的猜测是,如果你在ItemDate字段上放置一个索引,这不应该表现得太差。

答案 1 :(得分:0)

我不会让SQL这样做,它会创建一个效率低下的SQL查询(我认为)。

我可以创建一个存储过程,但如果数据量不是太大,我也可以使用Linq来对象:

List<x> items=dataContext.GetTable<X>().OrderByDescending(d => d.Date).ToList();//Bring data to memory

var res = items.Skip(1).Zip(items, (cur, prev) => cur.Value - prev.Value);

最后,我可能会使用foreach来提高可读性