Improving Blogs performance

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2011-12-21 12:21:30 -08:00
parent 698d6bbdff
commit 9f7175f6f5
5 changed files with 51 additions and 14 deletions
@@ -1,14 +1,17 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Common.Models;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Common.Models;
using Orchard.Core.Routable.Models; using Orchard.Core.Routable.Models;
using Orchard.Core.Routable.Services; using Orchard.Core.Routable.Services;
using Orchard.Data; using Orchard.Data;
using Orchard.Data.Conventions;
using Orchard.Tasks.Scheduling; using Orchard.Tasks.Scheduling;
namespace Orchard.Blogs.Services { namespace Orchard.Blogs.Services {
@@ -18,7 +21,11 @@ namespace Orchard.Blogs.Services {
private readonly IRepository<BlogPartArchiveRecord> _blogArchiveRepository; private readonly IRepository<BlogPartArchiveRecord> _blogArchiveRepository;
private readonly IPublishingTaskManager _publishingTaskManager; private readonly IPublishingTaskManager _publishingTaskManager;
public BlogPostService(IContentManager contentManager, IRepository<BlogPartArchiveRecord> blogArchiveRepository, IPublishingTaskManager publishingTaskManager) { public BlogPostService(
IContentManager contentManager,
IRepository<BlogPartArchiveRecord> blogArchiveRepository,
IPublishingTaskManager publishingTaskManager,
IContentDefinitionManager contentDefinitionManager) {
_contentManager = contentManager; _contentManager = contentManager;
_blogArchiveRepository = blogArchiveRepository; _blogArchiveRepository = blogArchiveRepository;
_publishingTaskManager = publishingTaskManager; _publishingTaskManager = publishingTaskManager;
@@ -57,7 +64,10 @@ namespace Orchard.Blogs.Services {
} }
public IEnumerable<BlogPostPart> Get(BlogPart blogPart, int skip, int count, VersionOptions versionOptions) { public IEnumerable<BlogPostPart> Get(BlogPart blogPart, int skip, int count, VersionOptions versionOptions) {
return GetBlogQuery(blogPart, versionOptions).Slice(skip, count).ToList().Select(ci => ci.As<BlogPostPart>()); return GetBlogQuery(blogPart, versionOptions)
.Slice(skip, count)
.ToList()
.Select(ci => ci.As<BlogPostPart>());
} }
public int PostCount(BlogPart blogPart) { public int PostCount(BlogPart blogPart) {
@@ -130,8 +140,11 @@ namespace Orchard.Blogs.Services {
private IContentQuery<ContentItem, CommonPartRecord> GetBlogQuery(ContentPart<BlogPartRecord> blog, VersionOptions versionOptions) { private IContentQuery<ContentItem, CommonPartRecord> GetBlogQuery(ContentPart<BlogPartRecord> blog, VersionOptions versionOptions) {
return return
_contentManager.Query(versionOptions, "BlogPost").Join<CommonPartRecord>().Where( _contentManager.Query(versionOptions, "BlogPost")
cr => cr.Container == blog.Record.ContentItemRecord).OrderByDescending(cr => cr.CreatedUtc); .Join<CommonPartRecord>().Where(
cr => cr.Container == blog.Record.ContentItemRecord).OrderByDescending(cr => cr.CreatedUtc)
.WithQueryHintsFor("BlogPost")
;
} }
} }
} }
@@ -19,14 +19,15 @@ namespace Orchard.Comments.Drivers {
return null; return null;
var commentsForCommentedContent = _commentService.GetCommentsForCommentedContent(part.ContentItem.Id); var commentsForCommentedContent = _commentService.GetCommentsForCommentedContent(part.ContentItem.Id);
Func<int> pendingCount = () => commentsForCommentedContent.Where(x => x.Status == CommentStatus.Pending).Count();
return Combined( return Combined(
ContentShape("Parts_Comments", ContentShape("Parts_Comments",
() => shapeHelper.Parts_Comments(ContentPart: part)), () => shapeHelper.Parts_Comments(ContentPart: part)),
ContentShape("Parts_Comments_Count", ContentShape("Parts_Comments_Count",
() => shapeHelper.Parts_Comments_Count(ContentPart: part, CommentCount: commentsForCommentedContent.Count(), PendingCount: commentsForCommentedContent.Where(x => x.Status == CommentStatus.Pending).Count())), () => shapeHelper.Parts_Comments_Count(ContentPart: part, CommentCount: commentsForCommentedContent.Count(), PendingCount: pendingCount)),
ContentShape("Parts_Comments_Count_SummaryAdmin", ContentShape("Parts_Comments_Count_SummaryAdmin",
() => shapeHelper.Parts_Comments_Count_SummaryAdmin(ContentPart: part, CommentCount: commentsForCommentedContent.Count(), PendingCount: commentsForCommentedContent.Where(x => x.Status == CommentStatus.Pending).Count())) () => shapeHelper.Parts_Comments_Count_SummaryAdmin(ContentPart: part, CommentCount: commentsForCommentedContent.Count(), PendingCount: pendingCount))
); );
} }
@@ -1,6 +1,6 @@
<ul class="pageStatus"> <ul class="pageStatus">
<li> <li>
@Display.CommentSummaryLinks(item: Model.ContentPart.ContentItem, count: Model.CommentCount, pendingCount: Model.PendingCount) @Display.CommentSummaryLinks(item: Model.ContentPart.ContentItem, count: Model.CommentCount, pendingCount: ((Func<int>)Model.PendingCount)()))
@T(" | ")&nbsp; @T(" | ")&nbsp;
</li> </li>
</ul> </ul>
@@ -11,6 +11,8 @@ using Orchard.Data;
using Orchard.Utility.Extensions; using Orchard.Utility.Extensions;
using NHibernate.Transform; using NHibernate.Transform;
using NHibernate.SqlCommand; using NHibernate.SqlCommand;
using System.Reflection;
using Orchard.Data.Conventions;
namespace Orchard.ContentManagement { namespace Orchard.ContentManagement {
public class DefaultContentQuery : IContentQuery { public class DefaultContentQuery : IContentQuery {
@@ -286,8 +288,31 @@ namespace Orchard.ContentManagement {
return criteria.GetCriteriaByPath(segment) ?? criteria.CreateCriteria(segment, JoinType.LeftOuterJoin); return criteria.GetCriteriaByPath(segment) ?? criteria.CreateCriteria(segment, JoinType.LeftOuterJoin);
} }
} public IContentQuery<T, TR> WithQueryHintsFor(string contentType) {
var contentItem = _query.ContentManager.New(contentType);
var contentPartRecords = new List<string>();
foreach (var part in contentItem.Parts) {
var partType = part.GetType().BaseType;
if (partType.IsGenericType && partType.GetGenericTypeDefinition() == typeof(ContentPart<>)) {
var recordType = partType.GetGenericArguments().Single();
contentPartRecords.Add(recordType.Name);
// iterate over every property seeking for [AggregateAttribute]
var aggregatedMembers = recordType.GetMembers(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.GetCustomAttributes(typeof(AggregateAttribute), false).Any())
.ToList();
if (aggregatedMembers.Any()) {
foreach (var aggregatedMember in aggregatedMembers) {
contentPartRecords.Add(recordType.Name + "." + aggregatedMember.Name);
}
}
}
}
return WithQueryHints(new QueryHints().ExpandRecords(contentPartRecords));
}
}
} }
internal static class CriteriaExtensions { internal static class CriteriaExtensions {
@@ -33,8 +33,6 @@ namespace Orchard.ContentManagement {
IContentQuery<TPart, TRecord> OrderByDescending<TKey>(Expression<Func<TRecord, TKey>> keySelector); IContentQuery<TPart, TRecord> OrderByDescending<TKey>(Expression<Func<TRecord, TKey>> keySelector);
IContentQuery<TPart, TRecord> WithQueryHints(QueryHints hints); IContentQuery<TPart, TRecord> WithQueryHints(QueryHints hints);
IContentQuery<TPart, TRecord> WithQueryHintsFor(string contentType);
} }
}
}