Get only the first row from a table in the Entity Framework

Background:

Entity Framework 4 with SQL Server 2008

Problem:

I have an Order table. Each row has a Timestamp column.

The user can select some time in the past, and I need to set the Order closer to the specified time, but this happened before the specified time. In other words, the last order before the specified time.

For example, if I have orders

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

and select the date 2010-07-22 , I have to get the 2009-09-24 order , because the last order is before the specified date.

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

This is closest to what I'm trying. However, I'm not sure exactly how the last statement works when translating to SQL, if at all.

Question:

Will this query retrieve all the data (earlier than userTime ) and then take the last item or translate it so that only one item will be returned from the database? My table may contain a very large number of rows (100000+), so performance is a problem here.

Also, how would I get the closest time in the database (not necessarily an earlier time)? In the example 2010-07-22 you can get 2010-11-02 , because it is closer to the date indicated below 2009-09-24 .

+4
source share
3 answers

In general, if you are concerned about how LINQ behaves, you should check what happens to SQL. If you haven't developed how to see how your LINQ queries turn into SQL, this should be the next thing you do.

As you noted in your comment, Last() not supported by LINQ to SQL , so this may be true for EF. Fortunately, it is easier to use First() :

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

Question:

Will this query retrieve all the data (before user time) and then accept the last item, or will it be translated in such a way that only one item will be returned from the database? My table can contain a very large number of rows (100000+), so performance is a problem here.

In this case, using the first () method, the request will be executed immediately, and it will be optimized so that it will receive 1 record. Most likely, the top one is selected (1). You really need to check genereated sql using the sql profilihg tool or using the datacontext log. Or you can use linqpad. linq-2-sql can lead to N + 1 queries if not used properly. This behavior is predictable, but in the beginning you really need to know.

+1
source

Try using:

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

This is the equivalent of TOP 1

+1
source

Source: https://habr.com/ru/post/1386462/


All Articles