这个查询获取一组评论,然后在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/
如果不分析输出的内容,这个问题是不可能回答的。但是,上面提供的链接应该为您提供自己执行此分析所需的工具。