我使用与内容类型同名的部分向内容类型添加了一个名为Website的LinkField。
ContentDefinitionManager.AlterTypeDefinition("MyContentType", a => a
.WithPart("CommonPart")
.WithPart("MyContentType")
.Creatable());
ContentDefinitionManager.AlterPartDefinition("MyContentType", cft => cft
.WithField("Website", a => a.OfType("LinkField").WithDisplayName("Website")
.WithSetting("FieldIndexing.Included", "True"))
.Attachable());
然后我在迁移过程中创建了一些默认内容项 我在添加字段数据之前创建项目,因为在创建项目之前设置它们的值时,我遇到了未更新字段的问题。 (请随意为此发光,但这不是我的问题)
var myItem = _orchardServices.ContentManager.New("MyContentType");
_orchardServices.ContentManager.Create(myItem);
var websitePart = myItem.Parts.FirstOrDefault(x => x.Fields.Any(y => y.Name == "Website"));
var websiteLinkField = websitePart .Fields.FirstOrDefault(x => x.Name == "Website") as LinkField;
websiteLinkField.Value = "http://www.google.com";
websiteLinkField.Text = "Link to google";
_orchardServices.ContentManager.Publish(myItem);
我意识到有更多动态的方式来访问该领域,但这似乎也有效。 当我查看项目时,数据显示出来,然后我继续进行查询。 我使用UI构建一个简单的查询来查找单词" google"在LinkField的文本中,我点击预览 没有找到结果。 然后我打开一个从迁移中创建的项目,然后点击" Save"按钮。 然后我再次尝试预览,现在保存的项目显示出来。
因此,当我保存一个我没有从迁移中执行的内容项时,我可以说出一些事情。但我一直在跨越所有角度的代码,我只是无法找到它。 我怀疑可能会有一些处理程序被触发以创建FieldIndex' es? (我知道如何触发Lucene索引的更新,但正如人们所预料的那样,它不会影响使用Projections模块查询字段,而且此时我真的丢失了。)
到现在为止,我只是在黑暗中盲目地刺伤 非常感谢我能得到的任何帮助,即使它只是让我回到了正确的方向。谢谢。
答案 0 :(得分:4)
你应该改变
_orchardServices.ContentManager.Create(myItem);
到
_orchardServices.ContentManager.Create(myItem, Orchard.ContentManagement.VersionOptions.Draft);
了解Orchard.Core.Core.Contents.Controllers.AdminController类的CreatePOST方法和Orchard.ContentManagement.DefaultContentManager类的Publish方法
在您调用Create(myItem)的情况下,然后创建已发布的内容项并正常调用所有处理程序(但尚未设置所需的数据)。当您调用Publish(myItem)时,没有任何事情发生(没有调用处理程序),因为您的内容已经发布。
答案 1 :(得分:2)
我已将此作为bug提出,如果您认为需要修复,请对其进行投票。
@Alexander Petryakov在他对正在发生的事情的描述中是正确的,他的工作可能是正确的方法,但是这种行为没有意义,这就是我提出错误的原因。您的问题中的代码会在存储在 Orchard_Framework_ContentItemVersionRecord 表中的数据的内容视图与存储在 Orchard_Projections_StringFieldIndexRecord 表中的数据的Projections视图之间创建不一致。基本上, Orchard_Projections_StringFieldIndexRecord 包含null,因为在更新字段后它还没有处理发布事件。
您拥有的代码主要执行以下操作:
对我来说,如果您更新内容项上的字段,那么您正在处理的项目的状态将不再发布(自您发布以来它已更改)。 Fields提供了允许您在更新时得到通知的钩子,因此解决问题的另一种方法是创建一个实现接口IFieldStorageEvents
的类,该接口在字段为时更新内容的已发布状态更新。
public class FieldUpdateEventHandler : IFieldStorageEvents {
public void SetCalled(FieldStorageEventContext context) {
context.Content.ContentItem.VersionRecord.Published = false;
}
}
这将允许您的原始代码在写入时运行。