Sam
Sam

Reputation: 1343

Repository pattern - Joining data from two tables

I'm making use of two repositories in my CommentService.

_commentRepository
_userRepository

Using the _commentRepository.GetAll() function I get a list of all my comments with the following information: [Id], [Content], [UserId].

I'm trying to create a list with all the comments and some of the matching user information obtainable by the _userRepository and store this in a DTO.

public ListOutput<CommentUserDto> GetCommentsWithUserInformation()
{
    var comments = _commentRepository.GetAll();

    // TODO: Add comment and user information to CommentUserDto.

    return new ListOutput<CommentUserDto>
    {
        Items = Mapper.Map<List<CommentUserDto>>(comments)
    };
}

How can I make this work?

Some possible ideas that I found:

  1. Creating a _commentUserRepository
  2. Using include to somehow join the two tables (I'm using E.F.)
  3. Create a Manager in my Domain layer that takes care of combining logic.

EDIT:

Comment model:

public class Comment
{
    public virtual string Content { get; set; }
    public virtual DateTime CreationTime { get; set; }
    public virtual long UserId { get; set; } // Id of User that posted Comment (always filled in)
}

User model:

public class User {
    public virtual string Name { get; set; }
    public virtual string Surname { get; set; }
    public virtual string Email { get; set; }  
    public virtual string Password { get; set; }
}

CommentUserDto: // Accessible class for views

public class CommentUserDto {
    public string Content { get; set; } // from comment
    public DateTime CreationTime { get; set; } // from comment
    public string PosterName { get; set; } // from user
    public string PosterSurname { get; set; } // from user
}

Upvotes: 0

Views: 2760

Answers (1)

Matt M
Matt M

Reputation: 3779

You don't need to do any of the three options you mention. If you have a navigation property from Comment to User, you can handle that in your mapping. Something like:

Mapper.CreateMap<Comment, CommentUserDto>().ForMember(dest => dest.UserName, opts => opts.MapFrom(src => src.User.UserName));

If you don't have a navigation property, then after your initial mapping, loop through the list of dto objects and call the appropriate _userRepository method to get the user information and populate the appropriate members of the dto object that way.

Edit

After seeing your models, what I would do (assuming a navigation property is not an option) is something like this:

var comments = _commentRepository.GetAll();

var results = new List<CommentUserDto>();

foreach(Comment comment in comments)
{
   var user = _userRepository.Get(comment.userId);
   var commentUserDto = new CommentUserDto
   {
      Content = comment.Content,
      CreationTime = comment.CreationTime,
      PosterName = user.Name,
      PosterSurname = user.Surname
   }

   results.Add(commentUserDto);
}

return results;

Upvotes: 1

Related Questions