我有一个 ItemHistory表
-----------------------------------
| Id | ItemId | DateTimeUtc |
|-----------------------------------|
| 1 | 1 | 2021-01-01 00:00:00 |
|----|------------------------------|
| 2 | 2 | 2021-01-01 00:00:00 |
|----|------------------------------|
| 3 | 2 | 2021-01-01 12:50:00 |
|----|------------------------------|
| 4 | 1 | 2021-01-02 17:00:00 |
|----|------------------------------|
| 5 | 3 | 2021-02-24 16:59:00 |
|----|------------------------------|
|... |... | ... |
------------------------------------
有必要实现一个数据获取,它需要一个集合ItemId和 time dateTimeUtc,并将及时返回Item每个最接近的条目(即,使差异Abs(DateTimeUtc - dateTimeUtc)最小)。据我了解,您需要对数据进行分组,ItemId并在每个组中排序,Math.Abs((x.DateTimeUtc - dateTimeUtc).TotalMilliseconds然后从每个组中选择第一条记录。我可怜的尝试做某事:
var result = context.Set<ItemHistory>()
.Where(x => itemIds.Contains(x.VehicleId))
.GroupBy(x => x.ItemId)
.OrderBy(x => Math.Abs((x.DateTimeUtc - dateTimeUtc).TotalMilliseconds))
.ToList();
但这当然不能编译(OrderBy行有错误)。在分组中,他并不强,原则上在 EntityFramework 中。因此,我寻求帮助。
我接受 c# 和 sql 中的答案
PS问题的标题很难表述。
实体框架版本:
<package id="EntityFramework" version="6.1.2" targetFramework="net45" />
我不知道 EF,但如果我必须使用普通的 Linq 来做,那么结果会是这样的
甚至如此
Entity Framework 无法处理在 C# 代码中有效的所有表达式。特别是,必须使用DbFunctions类的方法来实现 DateTime 类型差异。
另外,一定要投到
int,否则有若隐若现int?,不服Math.Abs。并且方法
First必须替换为FirstOrDefault. EF太挑剔了。在评论中,您写道数据正在上传很长时间。
我建议您尝试以下查询。
或者
它们看起来更可怕,但可能更快,因为它们没有排序。
我建议您启用请求日志记录:
第一行会在开启日志之前初始化上下文,对我们来说不重要的sql代码不会被包含在日志中。
所有三个查询看起来都很麻烦且效率低下。我原以为第二个和第三个生成的 sql 是相同的,但事实证明并非如此。
对大量数据进行尝试并报告结果。