1

目标:

我有一个小部件,它试图将具有匹配标签的博客文章返回到当前项目。

问题:

所以我在我的小部件中获取了当前的 ContentItem 并且我返回了TagsPart那个 ContentItem 的:

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

下面是我得到的错误。但是,我在这个发布的问题上读到 你不能做这种类型的过滤器,至少不是我打算这样做的方式。如何根据匹配的 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
4

1 回答 1

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);
}
于 2013-10-09T17:03:32.137 回答