orchard文档之-理解数据访问
数据访问在orchard 项目中与传统的web应用程序不一样,因为数据的建模是通过代码而不是数据库管理系统。你用代码定义数据属性,orchard 框架建立数据组件来保存数据。
如果您需要更改数据结构,你写代码来指定变化,这些变化会通过代码传播到数据库系统。这个代码为核心的模式包括抽象层,允许你在不同的内容类型(content type)中重用这些组件,添加或更改行为而不破坏其他层。
数据访问的关键概念如下:
- 记录(Records)
- 数据迁移(Data migrations)
- 内容处理器(Content handlers)
- 内容驱动器(Content drivers)
记录(Records)
一个记录 是一个代表内容组件(Content part)数据模式的类 。新建一条记录,你定义一个继承自 ContentPartRecord的类,然后添加你需要保存到内容组件的属性。每一个属性必须是virtual.比如,一个地图组件(Map Part)可能包含以下的记录:
namespace Map.Models { public class MapRecord : ContentPartRecord { public virtual double Latitude { get; set; } public virtual double Longitude { get; set; } } }
通常情况下,记录类(Record class)放置在Models的文件夹中,她的父类, ContentPartRecord
, 也包含一个id 的属性和一个 content item对象的引用。因此,MapRecord类的实例不仅仅包括Latitude
和 Longitude
属性,而且包括id
属性和 content item 对象,用来维护这个组件和其他内容的关系。
当你定义一个内容组件,你这样使用记录,如下代码所示:
namespace Map.Models { public class MapPart : ContentPart<MapRecord> { [Required] public double Latitude { get { return Record.Latitude; } set { Record.Latitude = value; } } [Required] public double Longitude { get { return Record.Longitude; } set { Record.Longitude = value; } } } }
注意只有与MapPart有关的数据定义了,你不需要定义任何需要维持MapPart和其他内容关系的属性。
关于 MapPart完整的例子,请看 Writing a Content Part.
数据迁移(Data Migrations)
创建一个记录类(record class)并不会创建数据表,它只是创建了数据模型。为了创建数据表,你必须写一个数据迁移类。
数据迁移类能让你创建和更新数据表的模型,在数据迁移类中的代码会在管理员选择启用或更新这个组件的时候执行。 更新的方法提供了一个数据模型更新的历史记录,当有一个可用更新时,站点管理员可以选择运行更新。
你可以通过运行以下的orchard命令行来创建一个数据迁移类:
codegen datamigration <feature_name>
这个命令会在该特征的根目录下创建一个 Migrations.cs 文件。 Create
方法自动添加到了 migration 类中. 在 Create
方法中, 你使用 SchemaBuilder
类来创建数据表,比如下面的 MapPart
特征.
namespace Map.DataMigrations { public class Migrations : DataMigrationImpl { public int Create() { // Creating table MapRecord SchemaBuilder.CreateTable("MapRecord", table => table .ContentPartRecord() .Column("Latitude", DbType.Double) .Column("Longitude", DbType.Double) ); ContentDefinitionManager.AlterPartDefinition( typeof(MapPart).Name, cfg => cfg.Attachable()); return 1; } } }
在定义数据模型属性的时候,通过包含 .ContentPartRecord()
,你保证了其他重要的属性包含在这个表中,在这个例子中,id属性和Latitude
和 Longitude
都包含在了此表中。
返回的数字很重要,因为它指定了特征的版本号。你将用版本号来更新模型。
你可以通过添加一个 UpdateFromN的方法来更新数据表,其中
N 是要更新 的版本号. 下面的代码展示了数据迁移类中有一个添加新列的更新方法:
namespace Map.DataMigrations { public class Migrations : DataMigrationImpl { public int Create() { // Creating table MapRecord SchemaBuilder.CreateTable("MapRecord", table => table .ContentPartRecord() .Column("Latitude", DbType.Double) .Column("Longitude", DbType.Double) ); ContentDefinitionManager.AlterPartDefinition( typeof(MapPart).Name, cfg => cfg.Attachable()); return 1; } public int UpdateFrom1() { SchemaBuilder.AlterTable("MapRecord", table => table .AddColumn("Description", DbType.String) ); return 2; } } }
更新方法返回2,因为新的列添加后,版本号是2,如果你要添加新的更新方法,更新方法应该命名为 UpdateFrom2()
.
当你添加了更新方法运行项目的时候,模块会安静的自动的更新。
内容处理器(Content Handlers)
内容处理器与 ASP.NET MVC的过滤器类似,在处理器中,你为特殊事件定义行为。在一个简单内容处理器中,你只定义内容组件的记录仓库,实例如下:
namespace Map.Handlers { public class MapHandler : ContentHandler { public MapHandler(IRepository<MapRecord> repository) { Filters.Add(StorageFilter.For(repository)); } } }
在更高级的内容处理器中,你定义类似特征发布或激活的事件行为,更多的关于内容处理器的信息,请查看 Understanding Content Handlers.
内容驱动器(Content Drivers)
内容驱动器类似 于ASP.NET MVC的控制器(controller). 它包含指定内容组件的代码,通常涉及到不同条件下创建数据形状的内容,比如显示或编辑模式。典型的,你重载Display和Editor方法,返回ContentShapeResult对象.