【问题标题】:Retrieve only the first row from a table in Entity Framework仅从实体框架中的表中检索第一行
【发布时间】:2012-01-20 22:31:25
【问题描述】:

背景:

实体框架 4,带有 SQL Server 2008

问题:

我有一张桌子Order。每行都有一列Timestamp

用户可以选择过去的某个时间,我需要得到最接近指定时间的Order,但那是在指定时间之前发生的。也就是说,指定时间之前的最后一个订单。

例如,如果我有订单

2008-01-12
2009-04-17
2009-09-24
2010-11-02
2010-12-01
2011-05-16

然后选择一个日期2010-07-22,我应该得到2009-09-24 order,因为这是指定日期之前的最后一个订单。

var query = (from oData in db.OrderDatas
            where oData.Timestamp <= userTime
            orderby oData.Timestamp ascending
            select oData).Last();

这是最接近我正在尝试的。但是,我不确定 Last 运算符在转换为 SQL 时究竟是如何工作的,如果它完全被翻译的话。

问题:

此查询将获取所有数据(早于userTime)然后获取最后一个元素,还是将其转换为仅从数据库返回一个元素?我的表可以容纳非常多的行(100000+),所以这里的性能是一个问题。

另外,如何检索数据库中最近的时间(不一定是更早的时间)?在2010-07-22 的示例中,会得到2010-11-02,因为它比2009-09-24 更接近指定的日期。

【问题讨论】:

    标签: c# sql-server-2008 entity-framework select


    【解决方案1】:

    一般来说,如果您关心 LINQ 的行为方式,您应该检查 SQL 发生了什么。如果您还没有弄清楚如何查看您的 LINQ 查询是如何转化为 SQL 的,那么您接下来要做的就是。

    正如您在评论中指出的那样,Last() isn't supported by LINQ to SQL 因此对于 EF 来说可能也是如此。幸运的是,改用First() 很容易:

    var query = (from oData in db.OrderDatas
                 where oData.Timestamp <= userTime
                 orderby oData.Timestamp descending
                 select oData).First();
    

    【讨论】:

    • 我刚刚查看了msdn.microsoft.com/en-us/library/bb399342.aspx。不支持最后一个运算符。所以我想我会坚持使用降序/第一个组合。
    • @KornelijePetak:这肯定是一个决定性因素 - 会相应地编辑我的帖子。
    • @KornelijePetak:请注意,该链接适用于 LINQ to SQL,而不是 EF。它可能适用于 EF。可能值得尝试并检查 SQL。
    • 我知道如何在 LINQ2SQL(使用 .Log)中检查生成的 SQL,并且我知道如何检查 ObjectQuery 的 CommandText,但在这种情况下这对我没有多大帮助,因为当 .应用了 First() 运算符,我不再有 ObjectQuery,而是单个 TSource。如何读取生成的实际执行的 SQL 语句?
    • @KornelijePetak:我不知道 - 但观察分析器中的查询肯定是一种方式。
    【解决方案2】:

    问题:

    此查询是否会获取所有数据(早于 userTime)然后取 最后一个元素,或者将它翻译成只有一个元素 会从数据库中返回吗?我的桌子可以容纳很大 行数(100000+),所以这里的性能是一个问题。

    在这种情况下,使用 first() 方法,查询将立即执行,并以仅检索 1 条记录的方式进行优化。很可能是 top(1) 选择。您确实需要使用 sql profilihg 工具或使用数据上下文的日志来检查生成的 sql。或者你可以使用 linqpad。如果使用不当,linq-2-sql 可能会导致 N+1 个查询。这种行为是完全可以预测的,但一开始你真的必须意识到这一点。

    【讨论】:

    • 在解决 LINQ 查询时,我不确定 LINQ2SQL 和 EF4 到底有多少不同,但我的问题是指 EF,以及您对 LINQ2SQL 的回答。
    • 对不起,我的错误。仍然会有相当的可比性。如果您使用分析器(来自 SQL Server 或使用 Express Anj 分析器),您仍然可以看到结果。我相信在 EF 中也会有一个优化的 select top(1) 而不是整个集合。
    【解决方案3】:

    尝试使用:

    var query = (from oData in db.OrderDatas
             where oData.Timestamp <= userTime
             orderby oData.Timestamp descending
             select oData).Take(1);
    

    相当于TOP 1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      • 2020-01-16
      • 2016-05-15
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多