eulercode
eulercode

Reputation: 1157

Linq Parent Child Query to SQL Server

I would like to do a querying to table with Parent Child Table Relationship as follow

tblCampaignComment (Parent)
tblCampaignCommentLike (Child)

I have come out with both method to return result as follow, but to me seems both method are not PERFORMANCE optimise. I will need to either take the performance hit on database or on the application.

Method A -> I need to perform multiple queries in database (for each comment)
Method B -> I need to perform foreach loop to filter, query and append. More code needed (it gonna be bad if i have a lot of child data to be process)

I wonder if there is a better one size fit all method that I am unaware of. If not, which of method A and method B is more preferable?

Method A (Select Child from Database)

var commentWithLikesList = entities.tblCampaignComment
    .Where(x => x.CampaignId == campaign_id)
    .Select(o => new CampaignCommentWithLikes
    {
        CampaignId = o.CampaignId,
        CommentId = o.CommentId,
        CommentLikes = entities.tblCampaignCommentLike.Where(x => x.CommentId == o.CommentId).ToList()
    }
    )
    .OrderBy(x => x.CampaignCommentCreatedDt)
    .Skip(skip)
    .Take(input.PageSize).ToList();

Method B (Group Join follow by for loop filtering)

var comments = entities.tblCampaignComment
    .Where(x => x.CampaignId == campaign_id)
    .OrderBy(x => x.CampaignCommentCreatedDt)
    .Skip(skip)
    .Take(input.PageSize)
    .GroupJoin(
        entities.tblCampaignCommentLike,
        cc => cc.CampaignId,
        ccl => ccl.CampaignId,
        (cc, ccl) => new
        {
            CampaignComment = cc,
            CampaignCommentLike = ccl
        }
    )
    .ToList();

var commentWithLikesList = new List<CampaignCommentWithLikes>();
foreach (var comment in comments)
{
    var commentWithLikes = new CampaignCommentWithLikes();
    commentWithLikes.CampaignId = comment.CampaignComment.CommentId;
    commentWithLikes.CommentId = comment.CampaignComment.CommentId;
    commentWithLikes.CommentLikes = new List<tblCampaignCommentLike>();

    if (comment.CampaignCommentLike != null)
    {
        foreach (var commentLike in comment.CampaignCommentLike)
        {
            if (commentLike.CommentId == commentWithLikes.CommentId)
            {
                commentWithLikes.CommentLikes.Add(commentLike);
            }
        }
    }

        commentWithLikesList.Add(commentWithLikes);
}

The outcome result should be as follow:

[
  {
    CampaignId: "1",
    CommentId: "1",
    ...
    ...
    CommentLikes: [
      {
    UserId: "1",
        UserName: "T",
      },
      {
        UserId: "1",
        UserName: "L",
      }
    ]
  },
  {
    CampaignId: "2",
    CommentId: "2",
    ...
    ...
    CommentLikes: [

    ]
  }
]

Upvotes: 0

Views: 515

Answers (1)

RubberChickenLeader
RubberChickenLeader

Reputation: 1003

When using entity framework you can eagerly load entities with an Include call.

Something like the following

entities.tblCampaignComment
        .Include(x => x.CampaignCommentLike) //This is the new line from the code in your question
        .Where(x => x.CampaignId == campaign_id)
        .OrderBy(x => x.CampaignCommentCreatedDt)
        .Skip(skip)
        .Take(input.PageSize)

This requires that CampaignCommentLike be a navigation property on tblCampaignComment but will let the database do an inner join between the two tables and EF will handle the parent child one to many relationship.

Upvotes: 1

Related Questions