This is a question which comes up a lot on the forums - a search should find some useful discussions.
The short answer is (as ever in software development) - "It depends". Mostly it depends on what you need to do with the data once you have retrieved it. If it is only going to be read-only then Typedlists/TypedViews/DynamicViews (they are all essentially the same thing under the hood - a thin wrapper around a DataTable) are the most efficient. They will be quicker to retrieve from the database, and will consume considerably less memory that using entities retrieved with PreFetch paths.
If however, you need to edit the data, then using an entity graph (an entity or set of entities, each with a number of related entities) are really your only choice.
That said, for small datasets (upto say 100 items, but YMMV) the overhead of using entities is barely noticable over that of using the datatable based methods, and I quite often find myself using them rather than having to construct one of the other methods, simply for speed of development.
Matt