2013-07-09 37 views
1

目標:如何在果園內篩選相關內容部分CMS查詢

我有試圖返回具有匹配標籤當前項目的博客帖子的Widget。

問題:

所以,我已經獲得了當前ContentItem在我的窗口小部件,我已經返回ContentItem的TagsPart

var itemTagsPart = _contentManager.Get<TagsPart>(currentContentItem.Id); 

,現在我想創建一個查詢,以返回具有匹配TagName的標記記錄的博客帖子。

var blogs = _contentManager.Query(VersionOptions.Published, "BlogPost") 
       .Join<TagsPartRecord>().Where(tpr => tpr.Tags.Any(tag => itemTagsPart.CurrentTags.Any(t => t.TagName == tag.TagRecord.TagName))) 
       .Slice(part.MaxPosts); 

不幸的是,關於篩選返回的TagsPartRecord記錄的謂詞,我得到一個空引用異常。我一直無法精確地減少哪個字段會導致這種情況,但我在謂詞中添加了空檢查(上面的代碼已將它們全部刪除,以便在此處保持清潔)。示例

var blogs = _contentManager.Query(VersionOptions.Published, "BlogPost") 
       .Join<TagsPartRecord>().Where(tpr => tpr.Tags != null && tpr.Tags.Any(tag => tag != null && itemTagsPart.CurrentTags.Any(t => t.TagName != null && t.TagName == tag.TagRecord.TagName))) 
       .Slice(part.MaxPosts); 

我甚至已經試過挑剔出itemTagsPart.CurrentTags.ToList()

以下是我收到的錯誤。不過,我讀到這posted Question ,你不能做這種類型的過濾器,至少不是我正在做的方式。我如何根據匹配的tagsParts過濾返回的博客文章?

版本: 1.7

錯誤:

Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator - NullReferenceException thrown from IContentPartDriver by TrueFit.RelatedBlogPosts.Drivers.RelatedBlogPostsWidgetDriver 
System.NullReferenceException: Object reference not set to an instance of an object. 
at NHibernate.Linq.Visitors.WhereArgumentsVisitor.GetExistsCriteria(MethodCallExpression expr) 
at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitMethodCall(MethodCallExpression expr) 
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) 
at NHibernate.Linq.Visitors.WhereArgumentsVisitor.GetExistsCriteria(MethodCallExpression expr) 
at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitMethodCall(MethodCallExpression expr) 
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) 
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitLambda(LambdaExpression lambda) 
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) 
at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitUnary(UnaryExpression expr) 
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) 
at NHibernate.Linq.Visitors.RootVisitor.HandleWhereCall(MethodCallExpression call) 
at NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall(MethodCallExpression expr) 
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp) 
at NHibernate.Linq.Visitors.NHibernateQueryTranslator.Translate(Expression expression, QueryOptions queryOptions) 
at Orchard.ContentManagement.DefaultContentQuery.Where[TRecord](Expression`1 predicate) in c:\inetpub\Orchard\src\Orchard\ContentManagement\DefaultContentQuery.cs:line 89 
at Orchard.ContentManagement.DefaultContentQuery.ContentQuery`2.Orchard.ContentManagement.IContentQuery<T,TR>.Where(Expression`1 predicate) in c:\inetpub\Orchard\src\Orchard\ContentManagement\DefaultContentQuery.cs:line 237 
at TrueFit.RelatedBlogPosts.Drivers.RelatedBlogPostsWidgetDriver.Display(RelatedBlogPostsWidgetPart part, String displayType, Object shapeHelper) 
at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3) 
at Orchard.ContentManagement.Drivers.ContentPartDriver`1.Orchard.ContentManagement.Drivers.IContentPartDriver.BuildDisplay(BuildDisplayContext context) in c:\inetpub\Orchard\src\Orchard\ContentManagement\Drivers\ContentPartDriver.cs:line 27 
at Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator.<>c__DisplayClassa.<BuildDisplay>b__9(IContentPartDriver driver) in c:\inetpub\Orchard\src\Orchard\ContentManagement\Drivers\Coordinators\ContentPartDriverCoordinator.cs:line 47 
at Orchard.InvokeExtensions.Invoke[TEvents](IEnumerable`1 events, Action`1 dispatch, ILogger logger) in c:\inetpub\Orchard\src\Orchard\InvokeExtensions.cs:line 17 
+0

您是否嘗試過ContentManager上的HqlQuery方法? –

回答

0

我工作的一個網站,我們基於一個單一的標籤名這樣的過濾博客文章:

// Get the blog that contains the posts you want to filter 
BlogPart blog = _contentManager.Query<BlogPart, BlogPartRecord>(VersionOptions.Published) 
                 .Join<TitlePartRecord>() 
                 .Where(t => t.Title == "your-blog-name") 
                 .Slice(0, 1).FirstOrDefault(); 

// Query for blog posts that contain a tag called "my-tag" 
IEnumerable<BlogPostPart> posts = _contentManager.Query(VersionOptions.Published, "BlogPost") 
               .Join<CommonPartRecord>() 
               .Where(cr => cr.Container == blog.Record.ContentItemRecord) 
               .Join<TagsPartRecord>() 
               .Where(tpr => tpr.Tags.Any(t => t.TagRecord.TagName == "my-tag")) 
               .WithQueryHints(new QueryHints().ExpandRecords<TagsPartRecord>().ExpandParts<TagsPart>()) 
               .Slice(maxPosts) 
               .Select(ci => ci.As<BlogPostPart>()); 

基於此,我猜測(儘管我沒有測試過),使用標籤名稱的字符串集合,您可以更改此行:

.Where(tpr => tpr.Tags.Any(t => t.TagRecord.TagName == "my-tag")) 

這條線(在您的標籤名稱收集myTags):

.Where(tpr => tpr.Tags.Any(t => myTags.Contains(t.TagRecord.TagName))) 

如果還是不行,您可以通過標籤的集合創建的博客帖子部分,環列表名稱,並使用原始查詢獲取每個標記名稱的博客文章:

// Get the blog that contains the posts you want to filter 
BlogPart blog = _contentManager.Query<BlogPart, BlogPartRecord>(VersionOptions.Published) 
                  .Join<TitlePartRecord>() 
                  .Where(t => t.Title == "your-blog-name") 
                  .Slice(0, 1).FirstOrDefault(); 
List<BlogPostPart> blogPosts = new List<BlogPostPart>(); 
foreach (string tag in myTags){ 
    // Query for blog posts that contain a tag called "my-tag" 
    IEnumerable<BlogPostPart> posts = _contentManager.Query(VersionOptions.Published, "BlogPost") 
                .Join<CommonPartRecord>() 
                .Where(cr => cr.Container == blog.Record.ContentItemRecord) 
                .Join<TagsPartRecord>() 
                .Where(tpr => tpr.Tags.Any(t => t.TagRecord.TagName == tag)) 
                .WithQueryHints(new QueryHints().ExpandRecords<TagsPartRecord>().ExpandParts<TagsPart>()) 
                .Slice(maxPosts) 
                .Select(ci => ci.As<BlogPostPart>()); 
    blogPosts.AddRange(posts); 
}