简体   繁体   English

Linq父子查询到SQL服务器

[英]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) tblCampaignComment(父)
tblCampaignCommentLike (Child) tblCampaignCommentLike(儿童)

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)方法 A -> 我需要在数据库中执行多个查询(对于每个评论)
Method B -> I need to perform foreach loop to filter, query and append.方法 B -> 我需要执行 foreach 循环来过滤、查询和 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?如果不是,方法 A 和方法 B 哪个更可取?

Method A (Select Child from Database)方法 A(从数据库中选择子项)

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)方法 B(Group Join 后跟 for 循环过滤)

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: [

    ]
  }
]

When using entity framework you can eagerly load entities with an Include call.使用实体框架时,您可以通过Include调用急切地加载实体。

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.这要求CampaignCommentLiketblCampaignComment上的导航属性,但会让数据库在两个表之间进行内部连接,并且 EF 将处理父子一对多关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM