【问题标题】:Entity Framework select most recent record for each type of record实体框架为每种类型的记录选择最近的记录
【发布时间】:2014-08-27 23:23:43
【问题描述】:

我有一个名为 values 的表,如下所示:

+-------+------------+-----------+----------+
|Id     |DateTime    |SensorId   |Value     |
+-------+------------+-----------+----------+

SensorId 是传感器详细信息表的外键。此值表中将有 10m+ 条记录。

我可以运行这个 sql 命令来返回每个 SensorId 的最新记录,它会在大约 0.3 秒内运行。

SELECT a.*
    FROM Values as a
    INNER JOIN (
        SELECT SensorId, MAX(ID) maxId 
        FROM Values
        GROUP BY SensorId
    ) b ON a.SensorId = b.SensorId 
        AND a.Id = b.maxId
ORDER BY a.SensorId ASC

如何在 c# 应用程序中实现与实体框架相同的输出,同时保持(或提高)性能?

【问题讨论】:

  • 把它做成一个视图,把视图添加到EF中。

标签: c# sql asp.net-mvc linq entity-framework


【解决方案1】:

使用 LINQ to Entities 和 lambda,您可以这样做:

dataContext.Values.GroupBy(p => p.SensorId)
     .Select(p => p.FirstOrDefault(w => w.Id == p.Max(m => m.Id)))  
     .OrderBy(p => p.SensorId).ToList()

其中 dataContext 是您的 ObjectContext 类的实例。 ToList() 编译查询。

【讨论】:

  • 这可行,但需要 6 秒才能运行。我需要它更快。
【解决方案2】:
  1. 我想它不可能达到比纯 SQL 查询更好的性能,因为通过使用 EF,您正在向流程中添加抽象层。
  2. 使用 GroupBy 命令时,EF 通常非常慢。我建议直接在EF中尝试sql查询 (此代码适用于 EF Core
context.Values.FromSqlRaw<Values>("SELECT a.*
    FROM Values as a
    INNER JOIN (
        SELECT SensorId, MAX(ID) maxId 
        FROM Values
        GROUP BY SensorId
    ) b ON a.SensorId = b.SensorId 
        AND a.Id = b.maxId
ORDER BY a.SensorId ASC").ToList<Values>();

FromSqlRaw 比普通的 Linq 查询更快。对于 EF,你可以用同样的方法尝试context.ExecuteQuery&lt;Values&gt;

【讨论】:

    猜你喜欢
    • 2021-02-25
    • 1970-01-01
    • 2012-05-24
    • 2012-02-19
    • 2014-11-19
    • 2021-12-13
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多