惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
Blog — PlanetScale
Blog — PlanetScale
J
Java Code Geeks
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
GbyAI
GbyAI
Vercel News
Vercel News
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
Jina AI
Jina AI
B
Blog
Recorded Future
Recorded Future
MyScale Blog
MyScale Blog
I
InfoQ
aimingoo的专栏
aimingoo的专栏
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
腾讯CDC
爱范儿
爱范儿
Last Week in AI
Last Week in AI
博客园 - 三生石上(FineUI控件)
博客园 - Franky
Schneier on Security
Schneier on Security
V
V2EX
TaoSecurity Blog
TaoSecurity Blog
H
Hacker News: Front Page
Cloudbric
Cloudbric
D
DataBreaches.Net
B
Blog RSS Feed
P
Palo Alto Networks Blog
云风的 BLOG
云风的 BLOG
NISL@THU
NISL@THU
I
Intezer
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Cyberwarzone
Cyberwarzone
F
Fortinet All Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
K
Kaspersky official blog
Forbes - Security
Forbes - Security

博客园 - 飞翔的天空

sp.net core部署到iis中出现 HTTP Error 502.5 - Process Failure 的解决办法 aspnet zero Swagger 不出现Authorize按钮的解决办法 Js获取当前日期时间及其它操作 js阿拉伯数字转中文大写 php学习点滴 excel合并单元格内容 EXCEL公式以指定分隔符从右往左截取字符 drupal学习FAQ drupal模块简介 js中三目运算及readonly的解决办法 Zxing中文乱码的简单解决办法 easyUI MVC3一些注意的东东(4) orchard模块编写的错误及其解决办法 orchard文档之-orchard工作原理 orchard文档之-搜索和索引 orchard文档之-更新站点到新的orchard版本 orchard文档之-创建自定义表单 准备把orchard的自己认为重要的文档翻译一遍 orchard文档之-理解内容处理器
orchard文档之-理解数据访问
飞翔的天空 · 2013-05-31 · via 博客园 - 飞翔的天空

数据访问在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类的实例不仅仅包括LatitudeLongitude 属性,而且包括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属性和LatitudeLongitude都包含在了此表中。

返回的数字很重要,因为它指定了特征的版本号。你将用版本号来更新模型。

你可以通过添加一个 UpdateFromN的方法来更新数据表,其中  是要更新 的版本号. 下面的代码展示了数据迁移类中有一个添加新列的更新方法:

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). 它包含指定内容组件的代码,通常涉及到不同条件下创建数据形状的内容,比如显示或编辑模式。典型的,你重载DisplayEditor方法,返回ContentShapeResult对象.

例子请查看 Accessing and Rendering Shapes.