当以编程方式设置值时查询不更新的字段索引

时间:2016-08-17 17:16:35

标签: orchardcms

我的模块通过控制器创建自定义内容项:

   private ContentItem createContentItem()
    {
        // Add the field
        _contentDefinitionManager.AlterPartDefinition(
            "TestType",
            cfg => cfg
            .WithField(
                "NewField",
                f => f
                    .OfType(typeof(BooleanField).Name)
                    .WithDisplayName("New Field"))
            );

        // Not sure if this is needed
        _contentDefinitionManager.AlterTypeDefinition(
            "TestType",
            cfg => cfg
                .WithPart("TestType")
            );

        // Create new TestType item
        var newItem = _contentManager.New("TestType");
        _contentManager.Create(TestItem, VersionOptions.Published);

        // Set the added boolean field to true
        BooleanField newField = ((dynamic)newItem).TestType.NewField as BooleanField;
        newField.Value = true;

        // Set title (as date created, for convenience)
        var time = DateTime.Now.ToString("MM-dd-yyyy h:mm:ss tt", CultureInfo.InvariantCulture).Replace(':', '.');
        newItem.As<TitlePart>().Title = time;

        return newItem;
    }

最终结果是一个新的TestType项,其字段设置为true。查看仪表板中的内容项以及检查数据库中的ContentItemVersionRecord确认值已正确设置。

但是,查询似乎无法在以这种方式设置的字段上正常工作。我找到了记录IntegerFieldIndexRecord,这是我假设投影用于填充查询结果页面的内容。在此,TestField的值保持为0(false),而不是1(true)。

转到内容项编辑页面,只需单击“保存”即可正确更新IntegerFieldIndexRecord,这意味着该值现在由查询选取。如何以编程方式为字段值更新记录?

迁移的相关部分:

SchemaBuilder.CreateTable(typeof(TestTypePartRecord).Name, table => table
            .ContentPartRecord()
        );

        ContentDefinitionManager.AlterTypeDefinition(
            "TestType",
            cfg => cfg
                .DisplayedAs("Test Type")
                .WithPart(typeof(TitlePart).Name)
                .WithPart(typeof(ContainablePart).Name)
                .WithPart(typeof(CommonPart).Name)
                .WithPart(typeof(IdentityPart).Name)
            );

编辑:对此的修复是在使用此调用更改字段值时手动更改投影索引记录:

_fieldIndexService.Set(testResultItem.As<FieldIndexPart>(),
     "TestType", // Resolves as TestTypePart, which holds the field
     "newField",
     "", // Not sure why value name should be empty, but whatever
     true, // The value to be set goes here
     typeof(bool));

2 个答案:

答案 0 :(得分:1)

在某些情况下,简单的contentManager.Publish()不会做。 我前段时间遇到过类似的问题,实际上实施了一个简单的帮助服务来解决这个问题。这是一段摘录:

public T GetStringFieldValues<T>(ContentPart contentPart, string fieldName)
{
    var fieldIndexPart = contentPart.ContentItem.As<FieldIndexPart>();
    var partName = contentPart.PartDefinition.Name;

    return this.fieldIndexService.Get<T>(fieldIndexPart, partName, fieldName, string.Empty);
}

private void SetStringFieldValue(ContentPart contentPart, string fieldName, IEnumerable<int> ids)
{
    var fieldIndexPart = contentPart.ContentItem.As<FieldIndexPart>();
    var partName = contentPart.PartDefinition.Name;
    var encodedValues = "{" + string.Join("},{", ids) + "}";
    this.fieldIndexService.Set(fieldIndexPart, partName, fieldName, string.Empty, encodedValues, typeof(string));
}

我实际构建了这个用于MediaLibrary-和ContentPicker字段(它们在内部将它们的值编码为字符串),因此它可能不适合您示例中的布尔字段。 但它实现起来并不困难,只需查看这些领域的现有驱动程序和处理程序。

答案 1 :(得分:0)

有两种方法可以解决这个问题:

1)通过调用ContentManager.Publish()确保新创建的项目已发布,因为Orchard.Projections.Handlers.FieldIndexPartHandler会监听发布事件以更新FieldIndexPartRecord

2)使用IFieldIndexService手动更新FieldIndexPartRecord,查看Orchard.Projections.Handlers.FieldIndexPartHandler的实施情况,了解如何执行此操作

希望这有帮助。

:编辑

由于调用了Create(...Published)ContentManager.Published()赢了,因为该项目已被视为已发布。

您可以执行以下操作以强制运行发布逻辑:

bool itemPublished = newItem.VersionRecord.Published;

// unpublish item first when it is already published as ContentManager.Publish() internally first checks for published flag and when set it aborts silently
//  -> this behaviour prevents calling publish listeners 
if (itemPublished)
  _contentManager.Unpublish(newItem);

// the following call will result in calls to IContentHandler.Publishing() / IContentHandler.Published()
_contentManager.Publish(newItem);

或者只是将项目创建为草稿,并在所有内容都正确设置后发布。