Stay away from the Repository/Unit of Work pattern if you're using Entity Framework. EF is itself an implementation of this pattern. If you want to abstract Entity Framework, then implement a service pattern that returns fully-baked data exactly how you need it. It's best illustrated with an example:
With EF/Repository
IQueryable<Post> posts = db.Posts.Where(m => m.BlogId == blog.Id && m.Status == PostStatuses.Published && m.PublishDate <= DateTime.Now).OrderBy(m => m.PublishDate);
With Service
List<Post> posts = service.GetPublishedPostsForBlog(blog);
The two key differences here are:
You're returning data already pulled from the database with the service; a repository/EF will return a queryable that may or may not have been executed against the database yet.
All your logic goes into the service method with a service. Whereas, with a repository/EF you build your query in place.
That said, don't get so hung up on the layers of your application. It's not about how many layers you have and what you call them, but rather about abstracting logic away from pieces of your application that shouldn't need to know how to construct that logic. A controller action to return a list of published blog posts, for example, shouldn't need to know what qualifies a post as being "published". That's domain logic that should go somewhere else (like the service method that returns this dataset). The idea is simply to follow the single-responsibility principle: a class/method/etc. should do one thing and do it well. Your controller action should only concern itself with returning the view (and doing the bare minimal amount of work to fetch what that view needs).
As far as mapping goes, the term explains exactly what you do, so I'm not sure of the confusion here. If you want to map Post
to PostViewModel
for example:
var model = new PostViewModel
{
Title = post.Title,
Content = post.Content,
...
}
Or with a list of objects, you can employ LINQ:
var model = posts.Select(m => new PostViewModel
{
Title = m.Title,
Content = m.Content,
...
}
If you question is simply: how do I do this easier? Then, you can look into a third-party mapping library like AutoMapper.