0

我无法从我在迁移中动态创建并附加到内容类型的附加部件的 DateTimeField 获取 DateTime。

结构是这样的:

CourseDate (ContentType)
   ProductPart (attached part from other project)
   CourseDatePart (attached part)
   TimeSpanPart (attached part from "dynamically" created part)

我正在尝试将作为 DateTimeField 的 StartDateTime 和 EndDateTime 拉出 TimeSpanPart。但是 DateTime 属性始终为 1/1/0001

这是我用来提取值的代码。除 TimeSpanPart 外,其他一切都有效。

    private EditCourseViewModel BuildEditorViewModel(CoursePart part)
    {
        var courseDates = _contentManager.Query<CourseDatePart, CourseDatePartRecord>().Where(x => x.CourseId == part.Id)
            .List<CourseDatePart>()
            .Select(x =>

                new CourseDateViewModel
                {
                    Id = x.Id,
                    StartDate = ((dynamic) x.ContentItem).TimeSpanPart.StartDateTime.DateTime,
                    EndDate = ((dynamic) x.ContentItem).TimeSpanPart.EndDateTime.DateTime,
                    Sku = ((dynamic) x.ContentItem).ProductPart.Sku,
                    IsDigital = ((dynamic) x.ContentItem).ProductPart.IsDigital,
                    Inventory = x.Inventory
                }

            );

当我检查 x.Record.ContentItemRecord.Data 的值时,我可以看到我想要的数据在那里:

    <Data><TimeSpanPart><StartDateTime>2013-09-02T06:20:00.0000000</StartDateTime><EndDateTime>2013-09-21T00:05:00.0000000</EndDateTime></TimeSpanPart></Data>

以下是迁移的相关部分:

      ContentDefinitionManager.AlterPartDefinition("TimeSpanPart", part=>part
            .Attachable()
            .WithField("StartDateTime", f=>f.OfType("DateTimeField").WithDisplayName("Start Date Time"))
            .WithField("EndDateTime", f=>f.OfType("DateTimeField").WithDisplayName("End Date Time"))
            );

        ContentDefinitionManager.AlterTypeDefinition("CourseDate", type=>type
            .WithPart(typeof(CourseDatePart).Name)
            .WithPart("TimeSpanPart")
            .WithPart(typeof(ProductPart).Name)
            );

编辑:

我更深入地研究了 Orchard InfosetStorageProvider 类,它管理字段的存储。在 BindStorage 方法中,它将 Data XML 元素传递给 Get 方法。但是不是传递 infosetPart.Infoset.Element (它具有我想要在上面显示的数据),而是传递 infosetPart.ContentItem.VersionRecord 因为它不为空;它是一个空的 XML 元素:<Data />

 return new SimpleFieldStorage(
                (name, valueType) => Get(infosetPart.ContentItem.VersionRecord == null ? infosetPart.Infoset.Element : infosetPart.VersionInfoset.Element, partName, fieldName, name),
                (name, valueType, value) => Set(infosetPart.ContentItem.VersionRecord == null ? infosetPart.Infoset.Element : infosetPart.VersionInfoset.Element, partName, fieldName, name, value));
        }

如何让它正确地将数据填充到 infosetPart.ContentItem.VersionRecord 中?这是 Orchard 中的一个错误,因为它传递了一个空的 xml <Data /> 元素而不是 null,因此它会将 infosetPart.Infoset.Element 传递给 Get 方法,还是我做错了什么?我不知道 infosetPart.ContentItem.VersionRecord 和 infosetPart.Infoset.Element 之间有什么区别。

4

1 回答 1

0

问题是在创建内容项时,我在创建内容项之前设置了字段的值。因此,它将值放入表 Orchard_Framework_ContentItemRecord 而不是 Orchard_Framework_ContentItemVersionRecord。

请参阅此处了解 Piedone 报告并由 Sebastien Ros 关闭的“错误”,它给了我答案: http: //orchard.codeplex.com/workitem/18412

我从来没有想过在创建对象后设置值。如果表 ContentItemVersionRecord 中的值被设置为 NULL 而不是 <Data /> ,它似乎仍然不太正确,它会起作用。

前:

            var courseDate = _contentManager.New("CourseDate");

            var courseDatePart = courseDate.As<CourseDatePart>();

            courseDatePart.CourseId = coursePart.Id;
            courseDatePart.Inventory = newDate.Inventory;

            dynamic courseDateDyn = courseDate;

            courseDateDyn.TimeSpanPart.StartDateTime.DateTime = newDate.StartDate.Value;
            courseDateDyn.TimeSpanPart.EndDateTime.DateTime = newDate.EndDate.Value;

            var product = courseDate.As<ProductPart>();

            product.Sku = newDate.Sku;
            product.IsDigital = newDate.IsDigital;

            //This should move up before setting field values.
            _contentManager.Create(courseDate);

后:

            var courseDate = _contentManager.New("CourseDate");

            var courseDatePart = courseDate.As<CourseDatePart>();

            courseDatePart.CourseId = coursePart.Id;
            courseDatePart.Inventory = newDate.Inventory;

            //This needs to happen before we set any values on the fields.
            _contentManager.Create(courseDate);

            dynamic courseDateDyn = courseDate;

            courseDateDyn.TimeSpanPart.StartDateTime.DateTime = newDate.StartDate.Value;
            courseDateDyn.TimeSpanPart.EndDateTime.DateTime = newDate.EndDate.Value;

            var product = courseDate.As<ProductPart>();

            product.Sku = newDate.Sku;
            product.IsDigital = newDate.IsDigital;
于 2013-09-19T05:49:26.667 回答