Models, ViewModels, DTOs in MVC 3 application

后端 未结 3 1275
無奈伤痛
無奈伤痛 2020-12-04 22:44

I have a web solution (in VS2010) with two sub-projects:

  1. Domain which holds the Model classes (mapped to database tables via Entit

3条回答
  •  有刺的猬
    2020-12-04 23:20

    introduce ViewModels which live in the WebUI project and expose IQueryables and the EF data context from the service to the WebUI project. Then I could directly project into those ViewModels.

    The trouble with this is you soon run into problems using EF trying to 'flatten' models. I encountered something similar when I had a CommentViewModel class that looked like this:

    public class CommentViewModel
    {
        public string Content { get; set; }
        public string DateCreated { get; set; }
    }
    

    The following EF4 query projection to the CommentViewModel wouldn't work as the couldn't translate the ToString() method into SQL:

    var comments = from c in DbSet where c.PostId == postId 
                   select new CommentViewModel() 
                   { 
                       Content = c.Content,
                       DateCreated = c.DateCreated.ToShortTimeString() 
                   };
    

    Using something like Automapper is a good choice, especially if you have a lot of conversions to make. However, you can also create your own converters that basically convert your domain model to your view model. In my case I created my own extension methods to convert my Comment domain model to my CommentViewModel like this:

    public static class ViewModelConverters
    {
        public static CommentViewModel ToCommentViewModel(this Comment comment)
        {
            return new CommentViewModel() 
            { 
                Content = comment.Content,
                DateCreated = comment.DateCreated.ToShortDateString() 
            };
        }
    
        public static IEnumerable ToCommentViewModelList(this IEnumerable comments)
        {
            List commentModels = new List(comments.Count());
    
            foreach (var c in comments)
            {
                commentModels.Add(c.ToCommentViewModel());
            }
    
            return commentModels;
        }
    }
    

    Basically what I do is perform a standard EF query to bring back a domain model and then use the extension methods to convert the results to a view model. For example, the following methods illustrate the usage:

    public Comment GetComment(int commentId)
    {
        return CommentRepository.GetById(commentId);
    }
    
    public CommentViewModel GetCommentViewModel(int commentId)
    {
        return CommentRepository.GetById(commentId).ToCommentViewModel();
    }
    
    public IEnumerable GetCommentsForPost(int postId)
    {
        return CommentRepository.GetCommentsForPost(postId);
    }
    
    public IEnumerable GetCommentViewModelsForPost(int postId)
    {
        return CommentRepository.GetCommentsForPost(postId).ToCommentViewModelList();
    }
    

提交回复
热议问题