当你新建一个有数据存储的 Module 时候,你的 Model 的字段会存储在数据库中对应的表中, 但
你可能还会添加其它一些 Field ,那么这些额外添加的 Field 究竟存放在了哪里呢?
在你只 Save 而不 Public 一个 ContentItem 时,这时这个 ContentItem 包含的所有 Field 的值,都会
以字符串的形式存放在表: Orchard_Framework_ContentItemVersionRecord 中的 Data 字段中。
存放的字符串如下所示:
<Data><TestFieldPart><TextField>Text Field</TextField><ContentPickerField></ContentPickerField><BooleanField>True</BooleanField><InputField>Input Field</InputField><MediaPickerField AlternateText="" Class="" Style="" Alignment="" Width="0" Height="0">~/Media/Default/images/图片004.jpg</MediaPickerField><NumericField>90</NumericField><DateTimeField>2012-11-29T12:40:00.0000000Z</DateTimeField><EnumerationField>Select an option</EnumerationField><LinkField Text="Text Field">http://www.baidu.com</LinkField></TestFieldPart><TestFieldType><ContentTypeBooleanField>True</ContentTypeBooleanField></TestFieldType></Data>
当你 Public 这个 Content Type 的时候,这些 Field 的值会被拷贝到 Projection 下面对应的几个表中。
至于为什么要拷贝到 Projection 下面,我现在还不知道,还有待进一步研究? 可能是方便做 Projection 的时候不用分离字符串了,直接按 Key-Value 的形式从相应的表中读出??
Numeric Field 会存在表 Orchard_Projections_DecimalFieldIndexRecord 中。
Boolean Field, DateTimeField 会存在表 Orchard_Projections_IntegerFieldIndexRecord 中,它们的值都被转换为了整形 。
ContentPickerField, EnumerationField, InputField, LinkField, MediaPickerField, TextField 的值会被存在表 Orchard_Projections_StringFieldIndexRecord 中,
它们的值会被转化为字符串。
其中需要注意的在 Orchard 中一个 Field 只能属于一个 ContentPart, ContentType 是不直接与 Field 关联的,在 Orchard 中你可以直接给一个 ContentType 添加
Field, 这是因为 Orchard 自动给你生成了一个与 ContentType 同名的 ContentPart。 所以 ContentType 包含许多 ContentPart,一个 ContentPart 又包含许多 Field。
而且当你添加一个 Field 时 比如 TextField ,如果没有为该 Field 赋值,默认这些 Field 是不会被显示在页面上的,
它们的值也不会被存放在数据库。 但像 ContentPickerField 和 ModiaPickerField 等,即使你不为它们赋值,它们也
会存入数据库中并显示在页面上。 包括你自己定义的 Field 的数据也会存入相应的表中。
这些都能够从代码中看出来, 其中 TestField 定义在 \Orchard.Core.Common.Fields\ 中, 其它 built in 的 Field 定义在 \Modules\Orchard.Fields\ 中。
如下面是 TextField 的 呈现视图,可见没有值时是不会显示的。
@if (HasText(name) && HasText(Model.Value)) { <p class="text-field"><span class="name">@name:</span> <span class="value">@(new MvcHtmlString(Html.Encode((HtmlString) Model.Value).ReplaceNewLinesWith("<br />$1")))</span></p> }
这些表的结构都一样, 如下图所示, Field 是以 Key-Value 的形式存放在数据库中, 其中 FieldIndexPartRecord_Id 是一个指向表 Orchard_Projections_FieldIndexPartRecord 的外键, 其值就是你的 Content Item(即Page) 的 Id, 表示一个 Page 上都有哪些 Field,当你访问该 Page 时, Orchard 就会从这些表中取出各个 Field 的值,由 Template 生成 View,同理取出页面的其它设置信息并生成 View, 最后所有的这些 PartialView 组合在一起形成一个完整的 Page 返回到客户端(Composite 模式)。
对了每个 Field 一般还有一些 Setting 的信息,那么这些 Settings 的信息又存放在哪里呢?
很显然 Setting 的信息一定存放在 Settings 表中,下面我简单描述一下存放 Settings 的几个表的功能。
表 : Settings_ContentFieldDefinitionRecord
存放系统中至今已经添加的 Field 的信息, 即你用了多少种的 Field,包括一个 Id 和 Name 字段。
表 : Settings_ContentPartDefinitionRecord
存放你系统中运用了多少种 Content Part, 每一个 Content Part 包含 Id, Name, Settings 等字段。
表: Settings_ContentPartFieldDefinitionRecord
存放每一个 Content Part 中都添加了哪些 Field, 包括 Id, Name ,一个指向对应的 Content Part(表 Settings_ContentPartDefinitionRecord)
和 Field(表 Settings_ContentFieldDefinitionRecord) 的外键等字段。
表 :Settings_ContentTypeDefinitionRecord
存放系统中现有 Content Type 的信息,包括 Id,Name,DisplayName, Settings 等字段。
表: Settings_ContentTypePartDefinitionRecord
显而易见存放每一个 Content Type 都包含哪些 Content Part。
先看这么多吧,可能有些 Field 的表没有说到,大家在使用中慢慢熟悉吧。