I really hope I have titled this somewhat correctly as I was struggling to put into words what I am asking but...
I am currently trying to get to grips with IEnumerables.
I have a class in my application like so:
public class MyDataRepo : IDisposable
{
private MyEntities context;
public MyDataRepo()
{ context = new MyEntities(); }
public IEnumerable<MyItem> GetMyItems()
{ return context.MyItems.AsEnumerable(); }
public void Dispose()
{ context.Dispose(); }
}
I thought then I could use it like so:
using (MyDataRepo repo = new MyDataRepo())
{
List<int> MyItemIDs = repo.GetMyItems().Where(x => x.ItemName == "Item Name")
.OrderBy(x => x.ItemMajorIssueNumber)
.ThenBy(x => x.ItemMinorIssueNumber)
.Select(x => x.ItemID).ToList();
}
But it is so much slower than just doing this:
using (MyEntities context = new MyEntities())
{
List<int> MyItemIDs = context.MyItems.Where(x => x.ItemName == "Item Name")
.OrderBy(x => x.ItemMajorIssueNumber)
.ThenBy(x => x.ItemMinorIssueNumber)
.Select(x => x.ItemID).ToList();
}
I just wondered why?
From the way I understood it, the IEnumerable
doesn't execute anything against the database until .ToList()
is called.
To me the seem like they should be the same query but the second is almost instant where as the first takes aroud 4-6 seconds.
I appreciate I may of totally mis understood IEnumerable
and it's usuage though.
I would ideally rather just call the IEnumerable<>
and apply filters to it then call .ToList()
to get results I desire than have to write several methods for all the queries against MyItems I will need.
Here we have difference with IEnumerable<T>
and IQueryable<T>
behaviour. When you put
List<int> MyItemIDs = repo
.GetMyItems()
.Where(x => x.ItemName == "Item Name")
...
which is in fact
List<int> MyItemIDs = context
.MyItems
.AsEnumerable() <- This is the felony!
.Where(x => x.ItemName == "Item Name")
...
you fetch all the records (say, all 1_000_000 ones) from RDBMS to the workstation by .AsEnumerable()
and only then filter them (Where
), order them (OrderBy
) etc.
On the contrary
List<int> MyItemIDs = context
.MyItems
.Where(x => x.ItemName == "Item Name")
...
is IQueryable<T>
up to the very end (.ToList()
) which means that SQL query created and all filtering (Where
), sorting (OrderBy
) will be perfomed on server side without unwanted fetch.