如何在Orchard CMS查询中过滤相关的内容部分 [英] How to filter related Content Parts within a Orchard CMS Query

查看:53
本文介绍了如何在Orchard CMS查询中过滤相关的内容部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:

我有一个小部件,试图将具有匹配标签的博客帖子返回给当前项目.

I have a widget that attempts to return blog posts that have matching tags to the current item.

问题:

所以我已经在窗口小部件中获取了当前的ContentItem,并返回了该ContentItem的TagsPart:

So I have acquired the current ContentItem in my widget and I have returned the TagsPart of that ContentItem:

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

我现在正尝试创建一个查询,以返回具有标签记录和匹配的TagName的博客帖子.

And I am now trying to create a query to return blog posts that have a tag record with a matching 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记录的谓词上,我得到了null引用异常.我还不能完全减少哪个字段会导致这种情况,但是我在谓词中添加了空检查(在上面的代码中,所有的空检查都已删除,以保持此处整洁).例子

Unfortunately, on the predicate for filtering the returned TagsPartRecord records, I get a null reference exceptions. I haven't been able to reduce exactly which field would cause this, but I have added null checks in my predicate (above code has them all removed to keep it clean for here). Example

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().

以下是我遇到的错误.但是,我阅读了此发布的问题 你不能做这种类型的过滤器,至少不是我要做的那样.如何根据匹配的tagParts过滤返回的博客文章?

Below is the error I am getting. However, I read on this posted Question that you can't do this type of filter, at least not the way I am going about it. How can I filter the returned blog posts based on matching 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

推荐答案

我正在一个网站上,我们基于这样的单个标签名称来过滤博客文章:

I'm working on a site where we filter blog posts based on a single tag name like this:

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

基于此,我猜(尽管我尚未测试过)带有标记名的字符串集合,您可以更改此行:

Based on this, I would guess (though I haven't tested) that with a string collection of tag names, you can change this line:

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

到此行(您的标签名称集合为myTags):

to this line (where your tag name collection is myTags):

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

如果这不起作用,则可以创建博客文章部分列表,遍历标记名称集合,并使用原始查询来获取每个标记名称的博客文章:

If that doesn't work, you can create a list of blog post parts, loop through your collection of tag names, and use the original query to get the blog posts for each tag name:

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

这篇关于如何在Orchard CMS查询中过滤相关的内容部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆