Well, assuming you are using Entity Framework (from tags).
When you execute the Linq expression you get an IQueryable collection. This IQueryable is not a truthy collection stored in memory with all the records fetched from the DB, it's kinda a statement where to query to the database server. I mean, You will not query the database since this IQueryable is accessed.
The IQueryable collection can be accessed through iteration or collection casting (such as IList, Array, ...).
/// This will yield item by item trough the loop.
IQueryable followers = /* linq expression */
foreach (var follower in followers)
{
// ...
}
The chunk above has a tiny better performance.
IQueryable followers = /* linq expression */
IList list = followers.ToList(); // At this point, the query is executed in the database server
foreach (var follower in list)
{
// ...
}
While this apporach is more safe.
It is a common practice to cast an IQueryable to an IList or similar to prevent concurrency issues, thread troubles, etc.
The important thing is to "seek" the IQueryable once all the actions on the query are done (filtering, sorting, ...).
Having an IQueryable like so
IQueryable followers = project.Followers;
you can now add actions to the IQueryable with no memory or performance cost.
followers = followers.Where(/* Any Func<Type, bool> action here*/);
followers = followers.OrderBy(/* Property KeySelector... */);
Once all the query is built, the query can be executed.
IList realDataInMemory = followers.ToList();
If you call the #ToList method at the first step.
IList followers = project.Followers.ToList();
the next Linq expressions will be executed to the in-memory collection.