十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用EF Core触发器构建真实CRUD应用:EntityFrameworkCore.Triggered示例项目全解析

用EF Core触发器构建真实CRUD应用:EntityFrameworkCore.Triggered示例项目全解析 用EF Core触发器构建真实CRUD应用EntityFrameworkCore.Triggered示例项目全解析【免费下载链接】EntityFrameworkCore.TriggeredTriggers for EFCore. Respond to changes in your DbContext before and after they are committed to the database.项目地址: https://gitcode.com/gh_mirrors/en/EntityFrameworkCore.TriggeredEntityFrameworkCore.Triggered 是一款专为 EF Core 打造的触发器库它让应用能够在你调用SaveChanges提交到数据库之前BeforeSave和之后AfterSave自动响应实体的变化。本文将完整解析官方仓库中的四个示例项目带你从零开始理解如何用 EF Core 触发器构建一个包含审计、软删除、自动注册课程的真实 CRUD 应用 示例项目地图4个由浅入深的场景打开仓库的samples/目录你会发现一套循序渐进的教程式示例目录场景适合谁samples/1 - HelloWorld/最小触发器示例3行核心代码完全的新手samples/2 - PrimarySchool/保存前查询数据库并级联写入想写业务逻辑的开发者samples/3 - StudentManagerAspNetCore/完整的 ASP.NET Core Razor Pages 学生管理系统想落地真实项目的工程师samples/4 - BlazorTests/触发器与 Blazor 前端集成想探索跨场景用法的人核心库源码位于src/EntityFrameworkCore.Triggered/其中Internal/Descriptors/目录下存放着六种触发器描述符BeforeSave/AfterSave/AfterSaveFailed 的同步与异步版本是理解框架内部机制的入口。5分钟上手HelloWorld示例的EF Core触发器HelloWorld 示例只有一个触发器但它展示了触发器的最小完整形态。核心文件在samples/1 - HelloWorld/Triggers/StudentAssignRegistrationDate.cs逻辑只有一句话public Task BeforeSaveAsync(ITriggerContextStudent context, CancellationToken cancellationToken) { context.Entity.RegistrationDate DateTime.Today; return Task.CompletedTask; }它的含义是每当一个Student实体即将被保存到数据库时自动把RegistrationDate属性填上今天日期。你不需要在每个新增学生的页面代码里重复写赋值逻辑触发器让数据库里永远不会出现忘记填注册日期的脏数据 ✅触发器通过实现IBeforeSaveAsyncTriggerStudent接口声明自己监听哪个实体类型注册时只需在UseTriggers配置块里加一行AddTriggerStudentAssignRegistrationDate()即可。进阶PrimarySchool示例——触发器中读写数据库第二个示例解决了一个常见问题新实体保存时需要联动修改其他实体。文件samples/2 - PrimarySchool/Triggers/StudentSignupToMandatoryCourses.cs实现了新生自动报名所有必修课程触发器在BeforeSaveAsync阶段被调用此时Student还未真正落库触发器通过构造器注入的ApplicationDbContext查询出所有IsMandatory true的课程为每个必修课检查是否已存在StudentCourse关联记录不存在就Add一条新的这些新增的StudentCourse记录会随着同一批次SaveChanges一起提交对业务代码完全透明。这个示例也点明了触发器与普通拦截器的最大差异触发器天然拿到 DbContext可以直接做完整的 LINQ 查询而不是仅仅观察一个实体的变化。真实CRUD应用全解析StudentManagerAspNetCore第三个示例是一个可直接dotnet run运行的学生管理系统Razor Pages SQLite也是全仓库最有价值的参考。它的页面覆盖学生与课程的完整 CRUD 操作而所有数据库必须遵守的规则都下沉到了触发器层。数据模型3个实体 2个接口特性模型定义在samples/3 - StudentManagerAspNetCore/Models.csStudent与Course都实现了ISoftDelete和IAudited两个标记接口StudentCourse学生与课程的多对多中间表Audit审计记录表保存每次变更的快照文本这里的巧妙之处是用接口作为特性开关实体只要实现ISoftDelete就自动获得软删除能力实现IAudited就自动获得审计能力。不需要继承基类也不需要给每个实体写样板代码。7个触发器的注册与职责一览所有触发器集中在Startup.cs的UseTriggers配置块中注册见samples/3 - StudentManagerAspNetCore/Startup.cs按职责可分为三类触发器监听对象生命周期职责AssignRegistrationDateStudentBeforeSave自动填充注册日期SignupToMandatoryCoursesStudentBeforeSave新生自动报名必修课AutoSignupStudentsCourseBeforeSave课程变必修时全体未报名学生自动补报BlockRemovalWhenCourseIsMandatoryStudentCourseBeforeSave阻止删除必修课的选课记录代码层外键约束SendWelcomingEmailStudentCourseAfterSave选课成功后发送欢迎邮件CreateAuditRecordIAuditedBeforeSave为任何审计实体生成变更快照EnsureSoftDeleteISoftDeleteBeforeSave把删除改写为标记删除时间逐个拆解关键触发器双向自动报名SignupToMandatoryCourses与AutoSignupStudents是一对互补的触发器——前者保证新学生加入时报名已有必修课后者保证课程被设为必修时补报所有老学生。两个方向都守住数据就永远一致。源码分别在Triggers/Students/SignupToMandatoryCourses.cs和Triggers/Courses/AutoSignupStudents.cs。AfterSave 做副作用SendWelcomingEmailTriggers/StudentCourses/SendWelcomingEmail.cs是仓库中唯一的 AfterSave 触发器。它选择 AfterSave 而非 BeforeSave 是有讲究的只有选课记录真正成功落库后才发送邮件避免邮件发了但数据没存上的尴尬。它通过构造器同时注入了ApplicationDbContext和EmailService演示了触发器可以像普通服务一样依赖注入任意应用服务。代码层软删除EnsureSoftDeleteTriggers/Traits/SoftDelete/EnsureSoftDelete.cs是软删除的最佳实践范例。它检测到ChangeType Deleted时把实体的DeletedOn设为当前时间然后把实体状态从Deleted改回Modified。结果就是你在页面上点删除实际执行的是 UPDATE 而非 DELETE数据永不丢失。通用审计CreateAuditRecordTriggers/Traits/Audited/CreateAuditRecord.cs利用触发器上下文中的UnmodifiedEntity变更前的实体与当前实体逐属性对比生成形如Name: 张三 李四的变更记录写入 Audit 表。因为它监听的是IAudited接口而非具体类Student 和 Course 都能被同一个触发器覆盖——这就是接口监听的威力。启动流程一条 UseTriggers 配置串起一切Startup.cs中的关键配置只有寥寥数行options.UseSqlite(Data sourcetest.db) .UseTriggers(triggerOptions { triggerOptions.AddTriggerTriggers.Traits.Audited.CreateAuditRecord(); triggerOptions.AddTriggerTriggers.Traits.SoftDelete.EnsureSoftDelete(); // … 其余 5 个触发器 });加上启动时的一次context.Database.EnsureCreated()整个应用即可运行。业务页面Pages/Students/、Pages/Courses/下的 Create/Edit/Delete 页面里没有任何一行触发器相关代码这就是触发器架构的核心收益业务规则与 UI 彻底解耦。触发器核心概念速查结合示例项目这些概念值得在动手前建立心智模型三种基本生命周期IBeforeSaveTrigger提交前可修改数据、IAfterSaveTrigger提交后做通知等副作用、IAfterSaveFailedTrigger保存失败时触发适合记录异常。接口定义位于src/EntityFrameworkCore.Triggered.Abstractions/ChangeType 判断context.ChangeType可区分 Added / Modified / Deleted是几乎所有触发器逻辑的第一道分支级联触发CascadingBeforeSave 触发器中新增的实体会继续触发它自己的触发器框架用EntityAndType策略默认防止无限循环可通过CascadeBehavior与MaxRecursion调整继承与优先级监听接口的触发器按最抽象到最具体排序执行触发器还可实现ITriggerPriority微调执行顺序见src/EntityFrameworkCore.Triggered.Abstractions/CommonTriggerPriorities.cs事务触发器src/EntityFrameworkCore.Triggered.Transactions/提供了 BeforeCommit / AfterCommit / BeforeRollback / AfterRollback 四个更细粒度的时机适合需要在事务真正提交后才执行的动作质量保障测试与编译期分析器仓库同样体现了工程化的完整度单元测试test/EntityFrameworkCore.Triggered.Tests/对内部每个组件触发器发现、上下文工厂、级联策略等都有独立测试集成测试test/EntityFrameworkCore.Triggered.IntegrationTests/中的CascadingSoftDeletes、EntityBags、LifetimeTests等场景验证真实数据库行为Roslyn 分析器EntityFrameworkCore.Triggered.Analyzers/提供编译期诊断当项目升级到新版后会提示你把旧版触发器接口迁移为新的异步接口并附带一键 CodeFix。这对跟随示例项目学习后升级版本的用户非常友好上手建议3步走先跑 Sample 3在samples/3 - StudentManagerAspNetCore/目录执行dotnet run在页面上新增学生、把课程标记为必修、尝试删除记录观察数据库里触发器悄悄完成的工作对照触发器源码按本文逐个拆解的顺序读Triggers/目录下的 7 个文件每个都不超过 40 行迁移到自己的项目从自动填充时间戳这类无风险触发器入手再逐步引入软删除、审计等跨实体规则需要更细粒度控制时再引入 Transactions 扩展包EntityFrameworkCore.Triggered 用非常薄的 API 解决了数据库不变量谁来守护这个 EF Core 生态的长期痛点。示例项目本身就是最好的文档——四个项目由浅入深覆盖了从单实体赋值到多实体级联、从标记接口到审计软删除的全部典型场景非常适合新手作为 EF Core 触发器的第一份学习材料 【免费下载链接】EntityFrameworkCore.TriggeredTriggers for EFCore. Respond to changes in your DbContext before and after they are committed to the database.项目地址: https://gitcode.com/gh_mirrors/en/EntityFrameworkCore.Triggered创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表