There are two issues.
IENumerable<Data> query = MyQuery();
//Later
foreach (Data item in query) {
//Process data
}
By the time the "Process Data" loop is reached, the query may no longer by valid. For example, if the query is being run on a DataContext that has already been Disposed, your code will throw an exception. This kind of thing becomes very confusing when you are processing a query in a different context than where you created it.
A secondary issue is that your connection will not be released until the "Process Data" loop completes. This is only a problem if "Process Data" is complex. This is mentioned at http://msdn.microsoft.com/en-us/library/bb386929.aspx :
Q. How long does my database connection remain open?
A. A connection typically remains open until you consume the query
results. If you expect to take time to process all the results and are
not opposed to caching the results, apply ToList to the query. In
common scenarios where each object is processed only one time, the
streaming model is superior in both DataReader and LINQ to SQL.
So, these issues are why you are being encouraged to ensure that the query is actually executed, e.g. by calling ToList()
. However, as Jimmy Suggests there is nothing stopping you from returning your List as an IEnumerable .
As a general rule, I recommend avoiding iterating over an IEnumerable more than once. Assuming consumers of your code follow this rule, I don't consider it a concern that someone might hit the database twice by executing the query twice.