For entity fetching:
Relations/Joins are used to filter or limit the returned records of the main entity you are fetching.
So you are not fetching records from related tables/entities.
Prefetchs are used to fetch related entities.
Please let me give you an example.
Example #1:
var filter = new RelationPredicateBucket();
filter.Relations.Add(CustomerEntity.Relations.OrderEntity..);
adapter.FetchEntityCollection(customers, filter);
The above code will fetch Customers, only those who have orders.
var prefetch = new PrefetchPath2(EntityType.OrderEntity);
prefetch.Add(OrderEntity.PrefetchPathCustomers);
prefetch.Add(OrderEntity.PrefetchPathOrderDetails);
adapter.FetchEntityCollection(customers, null, prefetch);
The above code will issue 3 SQL commands.
One to fetch all Orders.
One to fetch all Customers, filtered on the CustomerIds collected from the first query.
Another to fetch all OrderDetails filtered on OrderIds collected in the first query.
Then the graph is constructed at runtime, so you get each OrderEntity with its correct OrderDetails collection and the Correct Customer entity.