Linq可以优化这些子查询

  • 本文关键字:查询 优化 Linq c# sql linq
  • 更新时间 :
  • 英文 :


这个查询获取一组评论,然后在tblCommentVotes表中计算他们的赞成和反对。

目前,它通过select new语句以子查询的形式对这些进行计数。如果它在主查询中的某种分组中,这会更有效吗?如果可以的话,谁能告诉我怎么做,因为我不知道你会怎么做。

// Get comments
var q = (
    from C in db.tblComments
    where
        C.CategoryID == Category &&
        C.IdentifierID == Identifier
    join A in db.tblForumAuthors on C.UserID equals A.Author_ID
    orderby C.PostDate descending
    select new
    {
        C,
        A.Username,
        UpVotes = (from V in db.tblCommentVotes where V.CommentID == C.ID && V.UpVote == true select new { V.ID }).Count(),
        DownVotes = (from V in db.tblCommentVotes where V.CommentID == C.ID && V.UpVote == false select new { V.ID }).Count()
    }
)
.Skip(ToSkip > 0 ? ToSkip : 0)
.Take(ToTake > 0 ? ToTake : int.MaxValue);

您需要做的是在查询表达式中对db.tblCommentVotes进行左外连接,因为可能没有commentVotes?

当你有了这个,你应该能够执行一个查询,以获得你的结果。

它可能看起来像这样:

var q = (
   from C in db.tblComments
   where
      C.CategoryID == Category &&
      C.IdentifierID == Identifier
   join A in db.tblForumAuthors on C.UserID equals A.Author_ID
   // the following two lines are the left outer join thing. 
   join voteTemp in db.tblCommentVotes on voteTemp.CommentID equals C.ID into voteJoin
   from vote in voteJoin.DefaultIfEmpty()
   orderby C.PostDate descending
   group C by new { Comment = C, Username = A.Username } into g
   select new
   {
      g.Key.Comment,
      g.Key.Username,
      UpVotes = g.Count(x => x.UpVote),
      DownVotes = g.Count(x => !x.UpVote)
   }
)
.Skip(ToSkip > 0 ? ToSkip : 0)
.Take(ToTake > 0 ? ToTake : int.MaxValue);

这是未经测试的,甚至可能无法编译,但我认为应该是这样的

db.tblComments.Where(c => c.CategoryID == Category && c.IdentifierID == Identifier)
              .Join(db.tblForumAuthors, c => c.UserID, a => a.Author_ID,
                     (c, a) =>
                     new
                     {
                        CommentID = c,
                        AuthorName = a.UserName,
                        UpVotes = c.Join(db.tblCommentVotes, c => c.CommentID
                                                             v => v.CommentID,
                                                             (c, v) => v).Count(v => v.UpVote)
                        DownVotes = c.Join(db.tblCommentVotes, c => c.CommentID
                                                              v => v.CommentID,
                                                              (c, v) => v).Count(v => v.DownVote)
                     });

要优化,最好先测量。

  • 尝试使用LinqPad来查看生成的SQL
  • 然后使用SQL Server Management Studio查看该SQL的查询计划。

或:

  • 试着运行代码,看看SQL跟踪告诉你发生了什么

没有DB,很难(但很有趣)猜测Linq是否会导致单个查询或多个查询来计算UpVotes和DownVotes。我的猜测是,以这种方式计算UpVotes和DownVotes可能会相当昂贵-它可能导致每个评论额外2个查询。

http://www.thereforesystems.com/view-query-generate-by-linq-to-sql/

如果不分析输出的内容,这个问题是不可能回答的。但是,上面提供的链接应该为您提供自己执行此分析所需的工具。

相关内容

  • 没有找到相关文章

最新更新