LINQ根据时间将实体连接到实体(EF)相同的表

时间:2018-08-23 08:04:47

标签: c# sql-server entity-framework linq linq-to-sql

我有一个表,其中包含有关time和一些data的信息。预期的结果是在两行之间显示interval的{​​{1}}(以秒为单位)。

MyTable(来源):

data

预期结果:

------------------------------
|        Time        |  Data |
------------------------------
| 23.8.2018 14:00:00 |  abc  |
| 23.8.2018 14:00:02 |  def  |
| 23.8.2018 14:00:05 |  ghi  |
| 23.8.2018 14:00:06 |  jkl  |
------------------------------

我想到的可能的解决方案:

我得出结论,可以通过LINQ / SQL中的------------------- | interval| result| ------------------- | 2 | abc | | 3 | def | | 1 | ghi | | NULL | jkl | --optional result / might not exist ------------------- JOIN获得结果。如发现的那样,Linq to Entities不支持ZIP,但是应该在局部变量中工作。

类似的东西:

ZIP

考虑到var lTmp = lData.Zip(lData.Skip(1), (a, b) => new { interval = (b.Time - a.Time).Seconds, result = a.Value }).ToList(); ,我来到了“解决方案”,可以在下一行连接同一张表,但是我不知道该如何用LINQ编写。考虑到ID,我可以加入比上一个ID大(+1)的ID ,但是可能会丢失某些行,并且这些行必须按JOIN排序(不是ID)

最后但并非最不重要的一点是,我可以直接在SQL中编写如下内容:

Time

问题:

是否可以在LINQ(Linq to Entities)中编写这样的查询,怎么做?还是我需要将其放入存储过程/普通SQL查询中?

1 个答案:

答案 0 :(得分:2)

LINQ(所有形式)仅支持等联接,因此join不在。

但是您可以自己进行子查询,以按时间获取下一行:

from left in table
let right = (from x in table
             where x.Time > left.Time
             orderby x.Time
             select x).FirstOrDefault)
where right != null
select new {
    left.Data,
    interval = right.Time - left.Time
}

(您可能需要使用一种SQL函数来执行时间差。)

通常数据库可以优化这样的相关子查询,因此性能可能不会太差。否则,您可能需要发送自己的SQL。