CMS后端Web框架【免费下载链接】OrchardCoreOrchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.项目地址https://gitcode.com/gh_mirrors/or/OrchardCore点击查看免费下载Content Definitions内容定义是 Orchard Core 多租户架构下描述「Content Types内容类型、Content Parts内容部件、Content Fields内容字段」的元数据记录它决定了一个租户里可以创建什么样的内容、每个内容由哪些部件和字段构成。本指南围绕 src/docs/guides/content-definitions/README.md 的核心脉络展开先讲清默认的数据库存储与可选的File Content Definition文件存储两种模式各自的适用场景再手把手演示如何通过 Deployment Plan部署计划把ContentDefinition.json文件中的定义平滑迁移回数据库最后结合源码揭示底层存储契约与部署步骤的实现原理。读完本文你将掌握内容定义存储的切换思路、完整迁移流程并能理解背后的IContentDefinitionStore抽象与部署步骤机制。一、什么是 Content Definitions在 Orchard Core 中Content Definitions是某个租户tenant所使用的Content Types、Content Parts与Content Fields的完整记录。它们是内容建模的「蓝图」例如你在后台把Article类型挂上TitlePart、HtmlBodyPart添加TextField等操作最终都会落成一组结构化定义持久化到租户对应的存储中。Content Type Definition定义一个内容类型如Article、Page包括它挂载了哪些部件Parts与字段Fields以及可用的编辑器、显示设置等。Content Part Definition定义可复用的部件如TitlePart部件可以被多个内容类型引用。Content Field Definition定义字段如TextField、NumericField字段通常附加在部件或内容类型之上。从数据结构看这些定义被统一收纳进一个ContentDefinitionRecord文档对象中其中包含ContentTypeDefinitionRecords与ContentPartDefinitionRecords两个列表参见 ContentDefinitionRecord.cs[FileDocumentStore(FileName ContentDefinition)] public class ContentDefinitionRecord : Document { public IListContentTypeDefinitionRecord ContentTypeDefinitionRecords { get; set; } public IListContentPartDefinitionRecord ContentPartDefinitionRecords { get; set; } }注意这个类上标注的[FileDocumentStore(FileName ContentDefinition)]特性——这正是文件存储模式下文件名的由来文件名前缀ContentDefinition序列化后即ContentDefinition.json。二、两种存储方式数据库存储与文件存储1. 默认方式数据库存储Database Content Definition Store默认情况下Content Definitions 存储在数据库YesSql 文档表中。这是生产环境的推荐做法定义与站点数据一起落在数据库天然支持事务与备份体系多租户场景下每个租户的定义独立存储、互不干扰运行时通过内存缓存加速读取避免频繁访问数据库。其实现类为 DatabaseContentDefinitionStore.cs它通过IDocumentManagerContentDefinitionRecord完成文档的读取与更新public class DatabaseContentDefinitionStore : IContentDefinitionStore { private readonly IDocumentManagerContentDefinitionRecord _documentManager; public TaskContentDefinitionRecord LoadContentDefinitionAsync() _documentManager.GetOrCreateMutableAsync(); public TaskContentDefinitionRecord GetContentDefinitionAsync() _documentManager.GetOrCreateImmutableAsync(); public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) _documentManager.UpdateAsync(contentDefinitionRecord); }2. 可选方式文件存储File Content Definition Feature当启用名为File Content Definition的功能特性后Content Definitions 不再写入数据库而是保存在每个租户App_Data目录根部的ContentDefinition.json文件中。以默认租户为例路径为App_Data/Sites/Default/ContentDefinition.json其实现类为 FileContentDefinitionStore.cs唯一区别在于它使用的文档管理器绑定的是文件文档存储public class FileContentDefinitionStore : IContentDefinitionStore { private readonly IDocumentManagerIFileDocumentStore, ContentDefinitionRecord _documentManager; public TaskContentDefinitionRecord LoadContentDefinitionAsync() _documentManager.GetOrCreateMutableAsync(); public TaskContentDefinitionRecord GetContentDefinitionAsync() _documentManager.GetOrCreateImmutableAsync(); public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) _documentManager.UpdateAsync(contentDefinitionRecord); }从源码可以清晰地看到文件存储与数据库存储只是「落盘介质」不同对外暴露的接口完全一致——两者都实现了IContentDefinitionStore接口。该接口在 IContentDefinitionStore.cs 中定义了三个方法LoadContentDefinitionAsync()加载用于更新的可变定义不应缓存GetContentDefinitionAsync()从缓存获取用于共享的不可变定义SaveContentDefinitionAsync(record)更新存储并刷新缓存。而切换两种存储的关键在于依赖注入时注册哪个实现。参见 ServiceCollectionExtensions.cs 中的AddFileContentDefinitionStorepublic static IServiceCollection AddFileContentDefinitionStore(this IServiceCollection services) { services.RemoveAllIContentDefinitionStore(); services.AddScopedIContentDefinitionStore, FileContentDefinitionStore(); return services; }该方法先移除默认的数据库实现再注册文件实现。它由 OrchardCore.Contents 模块的 Startup.cs 中带[Feature(OrchardCore.Contents.FileContentDefinition)]特性的FileContentDefinitionStartup在ConfigureServices阶段调用[Feature(OrchardCore.Contents.FileContentDefinition)] public sealed class FileContentDefinitionStartup : StartupBase { public override void ConfigureServices(IServiceCollection services) { services.AddFileContentDefinitionStore(); } }这就是「启用/禁用功能特性即切换存储」的底层原理功能启用时注册文件实现功能禁用时回归默认的数据库实现。3. 两种存储的定位差异对比维度数据库存储默认文件存储File Content Definition数据落盘位置租户数据库YesSql 文档表App_Data/Sites/租户名/ContentDefinition.json适用阶段生产Production开发Development主要优势与站点数据统一管理适合线上运行文件可进版本控制便于代码评审与 diff 对比切换方式禁用File Content Definition特性即回退启用OrchardCore.Contents.FileContentDefinition特性官方文档给出的定位非常明确文件存储模式在项目的开发Development阶段非常有用——你可以把ContentDefinition.json纳入 Git 等版本控制系统团队成员改动内容建模后能直观地看到 diff评审更轻松当站点进入**生产Production**阶段则建议禁用该特性把 Content Definitions 存回数据库让定义与线上数据保持一致并由数据库统一管理。三、为什么开发阶段推荐文件存储内容定义的每一次改动新增类型、挂载部件、调整字段设置都会改写这组元数据。如果全部存进数据库改动不可见无法通过代码评审逐行审查「谁改了什么」难以把一套精心设计的内容模型随代码一起分发给其他环境。而文件存储让内容模型变得「像代码一样可评审、可复用」ContentDefinition.json是纯文本 JSON可以直接放进版本库拉取代码后新的开发环境启动即可获得与团队一致的内容模型冲突、回滚、分支合并都能用常规 Git 流程处理。需要注意的是文件存储在运行期同样会被内存缓存兜底ContentDefinitionManager维护类型/部件定义的缓存字典频繁读取不会直接打文件系统同时ContentDefinitionManager通过LoadContentDefinitionAsync可变与GetContentDefinitionAsync不可变两条路径区分「编辑中」与「只读共享」两种使用场景参见 ContentDefinitionManager.cs。四、迁移实战把 ContentDefinition.json 迁回数据库当你完成开发、准备把站点推向生产时需要把ContentDefinition.json中的定义迁移进数据库。官方推荐使用Deployment Plan部署计划作为迁移载体整个过程分三步下面逐一展开。Step One创建部署计划并导出定义在管理后台执行如下操作进入Tools - Deployments - Plans菜单点击Add Deployment Plan新建一个部署计划将部署计划命名为Content Definitions建议保持这个名称便于识别选中Content Definitions部署计划点击Add Step添加步骤选择Update Content Definitions更新内容定义步骤勾选Include all content types and parts definitions.包含全部内容类型与部件定义复选框执行该部署计划并在执行时选择File Download Target文件下载目标。执行完成后浏览器会下载一个名为ContentDefinitions.zip的文件到本地。这个压缩包内即包含了当前文件存储里的全部内容定义快照。这一步背后的部署步骤实现是 ContentDefinitionDeploymentStep.cs。从源码可以看到它的两个关键配置项public class ContentDefinitionDeploymentStep : DeploymentStep { public bool IncludeAll { get; set; } // 是否包含全部内容类型与部件 public string[] ContentTypes { get; set; } // 指定的内容类型列表 public string[] ContentParts { get; set; } // 指定的内容部件列表 }勾选「包含全部内容类型和部件定义」对应IncludeAll true导出时不做筛选若不勾选则可通过ContentTypes/ContentParts两个数组有选择地导出部分定义该步骤的Name为ContentDefinition界面上显示的中文标题Update Content Definitions由IStringLocalizer提供源码中Title S[Update Content Definitions]分类归入Content Management。Step Two禁用 File Content Definition 特性在把定义导入数据库之前需要先让系统「回到数据库存储」进入Tools - Features菜单找到名为File Content Definition的功能特性禁用该特性。如前文所述禁用该特性后FileContentDefinitionStartup不再注册依赖注入容器中的IContentDefinitionStore恢复为默认的DatabaseContentDefinitionStore实现参见 ServiceCollectionExtensions.cs 与 Startup.cs。提示此时站点处于「定义已从文件移除、尚未写入数据库」的过渡窗口建议在低峰期操作并确认已导出ContentDefinitions.zip且文件完好。Step Three导入部署包最后把第一步导出的文件导回系统进入Tools - Deployments - Package Import菜单选择第一步下载的ContentDefinitions.zip文件点击Import导入。导入过程会执行部署计划中的Update Content Definitions步骤把IncludeAll覆盖的全部内容类型与部件定义写回当前存储——此时当前存储已是数据库因此定义便成功落入了数据库。迁移完成后的校验导入完成后建议做如下检查在后台Content - Content Types中确认各内容类型及其部件、字段完整无缺新建一个示例内容项验证字段编辑、预览等行为与迁移前一致确认App_Data/Sites/Default/下不再生成或更新ContentDefinition.json特性已禁用。五、迁移原理小结为什么部署计划能胜任这件事整个迁移流程之所以成立是因为 Orchard Core 的部署体系本身就是「跨环境搬运配置」的标准通道导出阶段部署计划的ContentDefinitionDeploymentStep从当前存储文件读取定义打包成ContentDefinitions.zip切换阶段禁用特性后IContentDefinitionStore实现从FileContentDefinitionStore切换为DatabaseContentDefinitionStore导入阶段Package Import 执行部署步骤将定义写入新的存储数据库完成介质迁移。由于FileContentDefinitionStore与DatabaseContentDefinitionStore都实现同一个 IContentDefinitionStore 契约Load / Get / Save 三方法导入逻辑无需感知底层介质差异这也是「文件→数据库」可以无缝迁移的根本原因。六、总结Content Definitions是租户级的内容建模元数据包含类型、部件与字段三类定义统一存放在ContentDefinitionRecord文档中默认存数据库启用File Content Definition特性后改存App_Data/Sites/租户/ContentDefinition.json开发阶段便于版本控制与评审生产阶段建议存数据库两种介质共享IContentDefinitionStore抽象切换本质是依赖注入实现的替换AddFileContentDefinitionStore迁移三部曲创建部署计划导出ContentDefinitions.zip→ 禁用File Content Definition特性 → 通过 Package Import 导入部署包部署步骤 ContentDefinitionDeploymentStep 支持IncludeAll全量导出或按ContentTypes/ContentParts选择性导出迁移时按需勾选即可。掌握了这套流程你就能在「开发期用文件管理内容模型、上线前平滑切回数据库」之间自由切换让内容建模既保持代码级可评审性又具备生产环境的稳定性。赞分享CMS后端Web框架【免费下载链接】OrchardCoreOrchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.项目地址https://gitcode.com/gh_mirrors/or/OrchardCore点击查看免费下载相关推荐Ahoy 数据存储架构详解从数据库到自定义存储的完整迁移方案Ahoy 数据存储架构详解从数据库到自定义存储的完整迁移方案 Ahoy 是 Rails 生态中简单而强大的第一方分析解决方案其数据存储架构设计巧妙且高度可扩深入理解 agno 自定义学习存储Custom Learning Store从内存实现到数据库持久化的完整实战指南深入理解 agno 自定义学习存储Custom Learning Store从内存实现到数据库持久化的完整实战指南 导读 在 agno 的 Agent 2人工智能大模型AI AgentAgent 框架多智能体工具调用RAGAgent 工作流Agent 记忆Django Simple Captcha国际化指南多语言支持与本地化配置Django Simple Captcha国际化指南多语言支持与本地化配置 Django Simple Captcha是一个极其简单但高度可定制的Django后端应用安全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考