Umbraco CMS 的 SQLite EF Core 持久化层:迁移提供程序、重试策略与 OpenIddict 表结构解析
CMS后端【免费下载链接】Umbraco-CMSUmbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.项目地址https://gitcode.com/gh_mirrors/um/Umbraco-CMS点击查看免费下载本文围绕 Umbraco CMS 源码仓库中的Umbraco.Cms.Persistence.EFCore.Sqlite项目类库/NuGet 包目标框架 net10.0系统讲解 SQLite 在 EF Core 持久化层中的落地方式IMigrationProvider/IMigrationProviderSetup的职责与实现、SqliteRetryingExecutionStrategy应对SQLITE_BUSY/SQLITE_LOCKED的容错机制、四条历史迁移文件的具体内容以及新增迁移的标准操作流程。读完本文你将能够理解 Umbraco 中 EF Core 与 NPoco 双持久化栈如何并行工作并掌握为 SQLite 数据库编写、执行、同步 EF Core 迁移的完整方法。一、项目定位为 Umbraco 的 EF Core 层提供 SQLite 专属能力src/Umbraco.Cms.Persistence.EFCore.Sqlite/是一个薄提供程序thin provider项目它不定义新的业务模型而是把父项目Umbraco.Cms.Persistence.EFCore抽象出来的接口按 SQLite 特性落地。从项目文件 Umbraco.Cms.Persistence.EFCore.Sqlite.csproj 可以看出它只引用Microsoft.EntityFrameworkCore.Sqlite包和父项目的ProjectReference。它的四大职责迁移提供程序Migration Provider——执行 SQLite 专属的 EF Core 迁移迁移提供程序设置Migration Provider Setup——把 DbContext 配置为使用 SQLite并挂载瞬时错误重试策略迁移文件Migrations——面向 OpenIddict 数据表的 SQLite 迁移重试执行策略Retrying Execution Strategy——在 EF Core 操作上重试瞬时性的 SQLite 锁错误。与父项目的协作关系实现父项目 IMigrationProviderMigrateAsync/MigrateAllAsync和 IMigrationProviderSetupSetup复用父项目的UmbracoDbContext基类提供程序名取自父项目常量Constants.ProviderNames.SQLLite Microsoft.Data.Sqlite见 Constants-ProviderNames.cs与 SQL Server 的Microsoft.Data.SqlClient形成对照。目录结构与仓库实际文件一一对应src/Umbraco.Cms.Persistence.EFCore.Sqlite/ ├── Migrations/ │ ├── 20230622183638_InitialCreate.cs # No-opNPoco 创建基础表 │ ├── 20230807123456_AddOpenIddict.cs # 创建 OpenIddict 四张表 │ ├── 20240403141051_UpdateOpenIddictToV5.cs # OpenIddict v5 模式更新 │ ├── 20251006140958_UpdateOpenIddictToV7.cs # OpenIddict v7SQLite 下为 no-op │ └── UmbracoDbContextModelSnapshot.cs # 当前模型快照EF Core 自动生成 ├── EFCoreSqliteComposer.cs # DI 注册 ├── SqliteMigrationProvider.cs # IMigrationProvider 实现 ├── SqliteMigrationProviderSetup.cs # IMigrationProviderSetup 实现 └── SqliteRetryingExecutionStrategy.cs # 处理瞬时锁错误的 IExecutionStrategy二、三个核心组件逐个拆解1. EFCoreSqliteComposerDI 注册入口EFCoreSqliteComposer.cs 是 Umbraco 组合器IComposer在启动时把两个 SQLite 实现注册为单例public class EFCoreSqliteComposer : IComposer { public void Compose(IUmbracoBuilder builder) { builder.Services.AddSingletonIMigrationProvider, SqliteMigrationProvider(); builder.Services.AddSingletonIMigrationProviderSetup, SqliteMigrationProviderSetup(); } }这样父项目中的 EFCoreMigrationExecutor 在迁移时就能按提供程序名ProviderName与配置中ConnectionStrings.ProviderName匹配找到正确的实现。值得注意的是EFCoreMigrationExecutor的注释明确写着We need to do migrations outside of a scope due to SQLite——SQLite 下迁移必须在作用域之外执行这正是下一节MigrateAllAsync检查事务的原因。2. SqliteMigrationProvider命名迁移与全量迁移SqliteMigrationProvider.cs 通过IDbContextFactoryUmbracoDbContext创建上下文提供两种迁移入口MigrateAsync(EFCoreMigration)——执行指定的命名迁移先创建 DbContext再调用父项目的扩展方法MigrateDatabaseAsync(GetMigrationType(migration))该扩展定义在 DbContextExtensions.cs其内部读取迁移类上的MigrationAttribute拿到迁移 ID再交给 EF Core 的IMigrator.MigrateAsync。MigrateAllAsync()——执行全部待应用迁移直接调用context.Database.MigrateAsync()。关键约束MigrateAllAsync在事务激活时不能执行。源码在第 36-39 行做了显式防护if (context.Database.CurrentTransaction is not null) { throw new InvalidOperationException(Cannot migrate all when a transaction is active.); }GetMigrationType()的 switch 表达式把 EFCoreMigration 枚举定义在父项目迁移命名空间中映射到具体迁移类型EFCoreMigration.InitialCreate typeof(Migrations.InitialCreate), EFCoreMigration.AddOpenIddict typeof(Migrations.AddOpenIddict), EFCoreMigration.UpdateOpenIddictToV5 typeof(Migrations.UpdateOpenIddictToV5), EFCoreMigration.UpdateOpenIddictToV7 typeof(Migrations.UpdateOpenIddictToV7),枚举定义EFCoreMigrationInitialCreate 0、AddOpenIddict 1、UpdateOpenIddictToV5 2、UpdateOpenIddictToV7 3与 switch 必须保持同步——新增命名迁移时两处都要更新。3. SqliteMigrationProviderSetup配置 UseSqlite 重试策略SqliteMigrationProviderSetup.cs 实现了IMigrationProviderSetup.Setuppublic void Setup(DbContextOptionsBuilder builder, string? connectionString) { builder.UseSqlite(connectionString, x { x.MigrationsAssembly(GetType().Assembly.FullName); x.ExecutionStrategy(deps new SqliteRetryingExecutionStrategy(deps)); }); }两个关键动作MigrationsAssembly指向本程序集确保 SQLite 迁移文件只从这个项目加载ExecutionStrategy挂载自定义的SqliteRetryingExecutionStrategy。从 UmbracoDbContext.cs 的ConfigureOptions可以看到该Setup会被每一个UmbracoDbContext实例在构造时调用先解析IOptionsMonitorConnectionStrings拿到连接串与提供程序名再按提供程序名找到匹配的IMigrationProviderSetup执行配置。这意味着所有经 EF Core 访问 Umbraco 数据库的路径包括 OpenIddict 的令牌存储都会继承这套重试策略。三、SqliteRetryingExecutionStrategy为什么 SQLite 需要自定义重试Microsoft 官方没有为 SQLite 内置执行策略只有 SQL Server 版本因此 Umbraco 自行实现了一个用于解决 issue #22939长迁移期间 OpenIddict 令牌读取失败。问题根源SqliteRetryingExecutionStrategy.cs 的 XML 文档解释得很清楚SQLite 在数据库层面串行化写入者即使在 WAL 模式下schema 修改语句也会短暂阻塞读者若不加重试并发的 EF Core 读取例如 OpenIddict 对umbracoOpenIddictTokens的令牌校验就会把这种瞬时锁暴露为SqliteException直接导致请求失败。重试预算约 56 秒该策略继承ExecutionStrategy的默认参数——DefaultMaxRetryCount6 次与DefaultMaxDelay30 秒产生约0s, 1s, 3s, 7s, 15s, 30s的指数退避延迟序列合计约 56 秒的重试窗口。在 EF Core 延迟之外还需要知道SQLITE_BUSY错误码 5会被Microsoft.Data.Sqlite在连接Default Timeout默认 30 秒内自行重试SQLITE_LOCKED错误码 6不会内部重试立即返回因此 EF Core 的重试预算是对它的唯一缓冲。判定逻辑ShouldRetryOn沿着异常内部链向上遍历凡是遇到IsBusyOrLocked()判定通过的SqliteException就返回true继续重试protected override bool ShouldRetryOn(Exception exception) { for (Exception? current exception; current is not null; current current.InnerException) { if (current is SqliteException sqlite sqlite.IsBusyOrLocked()) { return true; } } return false; }IsBusyOrLocked定义在父项目 SqliteExceptionExtensions.cs覆盖三种错误码SQLITE_BUSY、SQLITE_LOCKED、SQLITE_LOCKED_SHAREDCACHE。该扩展的注释还说明NPoco 栈Umbraco.Cms.Persistence.Sqlite有一份平行的同名实现两个栈相互独立、刻意重复以保持分层干净。测试验证集成测试 SqliteRetryingExecutionStrategyTests.cs 精确复现了 issue #22939 的场景基线测试用单独的 SQLite 连接对umbracoLock表持有一个事务性UPDATERESERVED 写锁超过命令超时测试把DefaultTimeout缩短到 1 秒不带重试策略的 DbContext 无论读SingleOrDefaultAsync还是写ExecuteUpdateAsync都会抛出SqliteException且错误码必须是SQLITE_BUSY或SQLITE_LOCKED容错测试同样持锁 2.5 秒但换成挂载了SqliteRetryingExecutionStrategy的 DbContext首个尝试失败后退避重试锁释放后操作成功无异常冒出测试用Assert.Ignore(SQLite-only scenario.)保证只在 SQLite 环境运行。四、迁移历史四条迁移逐一解读迁移总览迁移日期用途InitialCreate2023-06-22No-op——NPoco 创建基础表AddOpenIddict2023-08-07创建 OpenIddict 表Applications、Tokens、Authorizations、ScopesUpdateOpenIddictToV52024-04-03OpenIddict v5 的 schema 更新UpdateOpenIddictToV72025-10-06SQLite 下为 no-op无需 schema 变更InitialCreate为什么是 No-op20230622183638_InitialCreate.cs 的Up方法只有一行注释No op. Existing tables are added by npoco. This will only create the history table.这是理解 Umbraco 持久化架构的关键NPoco 负责创建全部基础表EF Core 只管理 OpenIddict 相关表。迁移本身只创建 EF Core 的迁移历史表__EFMigrationsHistory不触碰业务表。AddOpenIddict创建四张 OAuth 表20230807123456_AddOpenIddict.cs 创建全部以umbraco前缀命名的四张表表名用途umbracoOpenIddictApplicationsOAuth 客户端应用umbracoOpenIddictAuthorizations用户授权umbracoOpenIddictScopesOAuth 作用域umbracoOpenIddictTokens访问/刷新令牌SQLite 专属特征在这份迁移里体现得非常直观——所有字符串列一律使用TEXT类型SQLite 没有 varchar例如Id table.Columnstring(type: TEXT, nullable: false), ClientId table.Columnstring(type: TEXT, maxLength: 100, nullable: true), Subject table.Columnstring(type: TEXT, maxLength: 400, nullable: true),迁移还建立了外键关系Tokens → Applications、Tokens → Authorizations、Authorizations → Applications与多个索引其中包括IX_umbracoOpenIddictTokens_ReferenceId唯一等 OpenIddict 查询路径依赖的关键索引。UpdateOpenIddictToV5OpenIddict v5 的 schema 演进20240403141051_UpdateOpenIddictToV5.cs 对应 OpenIddict v5 的模型变化对umbracoOpenIddictApplications做了四处修改把Type列重命名为ClientType新增ApplicationType列TEXT, maxLength 50新增JsonWebKeySet列TEXT新增Settings列TEXT。Down方法逐一回滚这些改动。UpdateOpenIddictToV7SQLite 与 SQL Server 的差异样本20251006140958_UpdateOpenIddictToV7.cs 在 SQLite 下是空操作// No changes required for Sqlite而同名兄弟迁移 SqlServer 版 则把umbracoOpenIddictTokens.Type从nvarchar(50)扩宽为nvarchar(150)。原因在于 SQLite 的TEXT类型不强制长度约束无需 schema 变更即可容纳更长的类型值——这是同一份 OpenIddict 升级在不同数据库上有不同落法的典型范例也说明给每个提供程序单独维护迁移文件的必要性。五、新增迁移的完整操作流程向 SQLite 提供程序添加新迁移时文档与源码共同给出以下步骤配置连接字符串在src/Umbraco.Web.UI/appsettings.json中设置有效的 SQLite 连接字符串模板见 appsettings.template.jsonConnectionStrings:umbracoDbDSN确保安装器/启动时能按ConnectionStrings.ProviderName匹配到Microsoft.Data.Sqlite从仓库根目录运行迁移命令UmbracoDbContext的 XML 注释与父项目文档均给出标准命令# 新增迁移SQLite dotnet ef migrations add %MigrationName% -s src/Umbraco.Web.UI -p src/Umbraco.Cms.Persistence.EFCore.Sqlite -c UmbracoDbContext # 回滚最后一条迁移SQLite dotnet ef migrations remove -s src/Umbraco.Web.UI -p src/Umbraco.Cms.Persistence.EFCore.Sqlite # 生成迁移脚本 dotnet ef migrations script -s src/Umbraco.Web.UI -p src/Umbraco.Cms.Persistence.EFCore.SqlServer同步 SQL Server 提供程序因为两个提供程序共享同一个EFCoreMigration枚举与UmbracoDbContext模型新增迁移必须同时添加到src/Umbraco.Cms.Persistence.EFCore.SqlServer/Migrations/对应命令把-p换成 SqlServer 项目否则另一数据库无法完成同一次升级更新命名映射如果是新增命名迁移即可被MigrateAsync(EFCoreMigration)单独调用的迁移需要同时更新父项目枚举 EFCoreMigration.cs位于Umbraco.Infrastructure/Migrations更新 SqliteMigrationProvider.GetMigrationType() 的 switch 表达式对应的 SQL Server 提供程序做同样的映射更新。六、项目专属注意事项自动生成文件Migrations/UmbracoDbContextModelSnapshot.cs由 EF Core 工具自动生成并维护不要手动编辑。它记录当前模型状态用于生成增量迁移时做 diff 对比。提供程序名速查Constants.ProviderNames.SQLLite Microsoft.Data.Sqlite; // SQLite Constants.ProviderNames.SQLServer Microsoft.Data.SqlClient; // SQL Server相关项目父项目Umbraco.Cms.Persistence.EFCore定义IMigrationProvider/IMigrationProviderSetup接口、UmbracoDbContext基类、EFCoreMigrationExecutor编排器与分布式锁机制兄弟项目Umbraco.Cms.Persistence.EFCore.SqlServerSQL Server 对等实现迁移文件名不同如20251006140751_UpdateOpenIddictToV7schema 变更策略也因数据库类型而异NPoco 栈Umbraco.Cms.Persistence.Sqlite负责基础表创建与数据访问与 EF Core 栈并行共存。七、核心文件速查表文件用途SqliteMigrationProvider.cs命名迁移与全量迁移执行SqliteMigrationProviderSetup.csDbContext 配置UseSqlite 重试策略SqliteRetryingExecutionStrategy.cs对瞬时 BUSY/LOCKED 错误重试EFCoreSqliteComposer.csDI 注册Migrations/*.cs四条 SQLite 迁移文件SqliteRetryingExecutionStrategyTests.cs重试策略的集成测试UmbracoDbContext.cs基类表名前缀与提供程序配置分发小结Umbraco.Cms.Persistence.EFCore.Sqlite虽小却集中体现了 Umbraco 持久化层两个关键设计一是按数据库提供程序拆分实现通过父项目的接口抽象让迁移与配置完全可插拔二是用自定义重试策略补偿 SQLite 的锁语义把长迁移期间 OpenIddict 令牌校验的瞬时失败从硬错误变成可重试的等待。理解这三者Composer 注册 → Provider 迁移 → Retrying 容错的协作链路就能在 Umbraco 上放心使用 SQLite 作为开发或轻量部署数据库。赞分享CMS后端【免费下载链接】Umbraco-CMSUmbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.项目地址https://gitcode.com/gh_mirrors/um/Umbraco-CMS点击查看免费下载相关推荐AI-on-the-edge-device 配置参数全览从 config.ini 到参数文档体系的完整指南AI on the edge device 配置参数全览从 config.ini 到参数文档体系的完整指南 导读 本文以 param docs/templatCMS后端Umbraco-CMS数据持久化策略NPoco与EF Core双轨并行的技术实现Umbraco CMS数据持久化策略NPoco与EF Core双轨并行的技术实现 Umbraco CMS作为一款流行的ASP.NET内容管理系统其数据持久化CMS后端Workflow Core 的 SQLite 持久化提供程序安装配置、底层原理与实战要点Workflow Core 的 SQLite 持久化提供程序安装配置、底层原理与实战要点 本指南围绕开源 .NET 工作流引擎 Workflow Core 的后端工作流自动化流程编排上一篇react-admin 数据请求完全指南从 useDataProvider 到 Query/Mutation Hooks 与乐观更新下一篇Neovide 命令行参数完整参考窗口、渲染、进程与 macOS 专属选项实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Akka.NET Cluster 扩展(Cluster Extension)实战指南:订阅集群事件与获取集群状态

Akka.NET Cluster 扩展(Cluster Extension)实战指南:订阅集群事件与获取集群状态

后端微服务 【免费下载链接】akka.net Canonical actor model implementation for .NET with local distributed actors in C# and F#. 项目地址: https://gitcode.com/gh_mirrors/ak/akka.net 点击查看 免费下载 Akka.Cluster 本质上是一个 ActorSystem 扩展&…

2026/10/13 12:46:50 阅读更多 →
如何 10 分钟搭起 SimpleMindMap 思维导图:本地运行、场景与导出教程

如何 10 分钟搭起 SimpleMindMap 思维导图:本地运行、场景与导出教程

如何 10 分钟搭起 SimpleMindMap 思维导图:本地运行、场景与导出教程 【免费下载链接】mind-map SimpleMindMap(思绪思维导图):一个强大的思维导图。A powerful mind map. 项目地址: https://gitcode.com/GitHub_Trending/mi/mi…

2026/10/13 12:46:50 阅读更多 →
AI工程师的国庆七天:技术快闪战背后的节奏逻辑与工程实践

AI工程师的国庆七天:技术快闪战背后的节奏逻辑与工程实践

1. 项目概述:一场没有硝烟的AI技术快闪战“国庆七天,AI圈没一天消停”——这句话不是夸张修辞,而是过去七年里每逢长假都反复验证的行业真实切片。它背后指向的,不是节日氛围的缺席,而是一套高度压缩、高频迭代、强对抗…

2026/10/13 12:46:50 阅读更多 →

最新新闻

Spring Boot+HTML5问卷调查系统实战:从课设到可部署应用

Spring Boot+HTML5问卷调查系统实战:从课设到可部署应用

1. 一次课设的重新思考:从“交差”到“能用的系统”如果你是因为毕设或课程设计搜到这个题目,那我想先聊点实在的。Spring Boot HTML5的问卷调查系统,属于那种“看起来不复杂,但真要做得顺滑还是有一堆细节”的项目。很多同学做的…

2026/10/13 13:29:09 阅读更多 →
NPM包管理器深度解析:从配置文件到依赖管理实战

NPM包管理器深度解析:从配置文件到依赖管理实战

1. NPM是什么:先理清包管理器的职责边界接手一个旧项目,最怕的不是业务逻辑难读,而是npm install跑完,终端里飘出一大片红色报错。我见过不少开发者,第一反应就是把提示里的--force直接复制上去装完拉倒,结…

2026/10/13 13:29:09 阅读更多 →
Oracle补丁包安装全流程:从opatch apply到datapatch避坑指南

Oracle补丁包安装全流程:从opatch apply到datapatch避坑指南

简介:这是一份面向 Linux x86-64 环境的补丁工具资源,编号 p27734982_112040,用于在安装有 p13390677_112040 补丁的系统上修复已知问题、增强功能,适合系统运维、DBA 及中间件管理人员在升级或安全加固时使用。包内共 1181 个文件…

2026/10/13 13:29:09 阅读更多 →
用 Sandboxie 沙盒隔离软件测试风险:从安装包验证到环境零残留

用 Sandboxie 沙盒隔离软件测试风险:从安装包验证到环境零残留

如果你也干过软件测试,应该懂这样一种感觉:拿到一个来路不明的安装包,明知道它可能往系统里塞一堆东西,但为了验证功能,还是咬着牙双击“下一步、下一步、完成”,然后祈祷卸载的时候能卸干净。结果经常是装…

2026/10/13 13:29:09 阅读更多 →
Oracle 11.2.0.4补丁安装与回滚实战:以p27734982为例

Oracle 11.2.0.4补丁安装与回滚实战:以p27734982为例

简介:这是一份专为 Linux x86-64 环境设计的补丁资源包,本质属于补丁工具,用于在已安装 p13390677_112040 补丁的基础上做增量增强或缺陷修复,面向系统管理员、数据库运维与自动化脚本编写人员。压缩包共 1181 个文件,…

2026/10/13 13:29:09 阅读更多 →
基于机器学习的分布式系统故障诊断:特征工程与工程落地实践

基于机器学习的分布式系统故障诊断:特征工程与工程落地实践

简介:基于机器学习的分布式系统故障诊断系统完整项目源码,配套文档说明,适用于计算机、人工智能、通信工程、自动化等专业学生作为毕业设计、课程设计或初期项目演示。项目聚焦分布式环境下的异常检测与故障定位,代码已经运行验证…

2026/10/13 13:28:06 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →