Linq可以优化这些子查询吗?

时间:2011-04-14 23:13:21

标签: c# sql linq

此查询采用一组注释,然后在tblCommentVotes表中计算其upvotes和downvotes。

目前,它通过select子句以子查询的形式对这些进行计数。如果它在主查询中属于某种类别,这会更有效吗?如果可以的话,任何人都可以告诉我如何做到这一点,因为我无法弄清楚你将如何做到这一点。

// 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);

4 个答案:

答案 0 :(得分:3)

您需要做的是在查询表达式中执行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);

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

答案 1 :(得分:1)

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)
                     });

答案 2 :(得分:1)

要优化它,最好先测量。

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

或:

  • 尝试运行代码并查看SQL跟踪告诉您的内容

如果没有数据库,那么猜测Linq是会导致单个查询还是多个查询来计算UpVotes和DownVotes是非常困难的(但很有趣)。我的猜测是以这种方式计算UpVotes和DownVotes可能非常昂贵 - 每次评论可能会导致额外的2个查询。

答案 3 :(得分:0)

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

没有分析输出什么是这个问题是不可能回答的......但是上面提供的链接应该为您提供自己执行此分析所需的工具。