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

发布于 2024-11-01 15:51:00 字数 834 浏览 1 评论 0原文

此查询获取一组评论,然后在 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);

This query takes a group of comments, then counts their upvotes and downvotes in the tblCommentVotes table.

At the moment, it counts these via the select new statement, in the form of a subquery. Would this be more efficient if it was in some sort of group by in the main query? Also if it would, could anyone show me how to do this, as I can't work out how you would do this.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦途 2024-11-08 15:51:01

http://www.thereforesystems.com/view-query- 在不分析输出内容的情况下生成 by-linq-to-sql/

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

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

without analyzing whats being output this question is impossible to answer.. however the link provided above should give you the tools necessary to perform this analysis yourself.

残疾 2024-11-08 15:51:00

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

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

What you need to do is to do an left outer join of the db.tblCommentVotes in the query expression, cause probably there might be no commentVotes?

When you have that, you should be able to perform ONE query in order to get your result.

It might look like this:

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

This is untested and might not even compile, but I think it should be something like this.

倚栏听风 2024-11-08 15:51:00
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)
                     });
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)
                     });
情话已封尘 2024-11-08 15:51:00

要优化,最好先进行测量。

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

,或者:

  • 尝试运行代码并查看 SQL 跟踪告诉您正在发生的情况

如果没有数据库,这将非常困难(但很有趣) )来猜测 Linq 是否会产生单个查询或多个查询来计算 UpVotes 和 DownVotes。我猜测是,以这种方式计算 UpVotes 和 DownVotes 的成本可能相当高 - 它可能会导致每个评论产生 2 个额外的查询。

To optimise it's best first to measure.

  • Try, using something like LinqPad to view the generated SQL
  • Then use SQL Server Management Studio to see the query plan for that SQL

or:

  • Try running the code and seeing what SQL trace tells you is happening

Without the DB, it's quite hard (but fun) to guess whether that Linq will result in a single query or in multiple queries for working out the UpVotes and DownVotes. My guess is that calculating the UpVotes and DownVotes this way could be quite expensive - it may result in 2 additional queries per comment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文