aigroup-workflow 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/fix-build.md +10 -5
- package/.claude/commands/init-project.md +13 -8
- package/.claude/commands/plan.md +15 -8
- package/.claude/commands/review.md +12 -6
- package/.claude/commands/tdd.md +11 -5
- package/.claude/commands/workflow-start.md +20 -11
- package/.claude/settings.json +28 -0
- package/.codex/agents/architect.toml +207 -0
- package/.codex/agents/build-error-resolver.toml +110 -0
- package/.codex/agents/code-reviewer.toml +233 -0
- package/.codex/agents/doc-updater.toml +103 -0
- package/.codex/agents/e2e-runner.toml +103 -0
- package/.codex/agents/get-current-datetime.toml +23 -0
- package/.codex/agents/init-architect.toml +181 -0
- package/.codex/agents/planner.toml +208 -0
- package/.codex/agents/refactor-cleaner.toml +81 -0
- package/.codex/agents/rust-reviewer.toml +90 -0
- package/.codex/agents/security-reviewer.toml +104 -0
- package/.codex/agents/tdd-guide.toml +87 -0
- package/AGENTS.md +2 -2
- package/CLAUDE.md +23 -1
- package/LICENSE +20 -20
- package/README.md +333 -333
- package/agents/a11y-architect.md +141 -141
- package/agents/architect.md +211 -211
- package/agents/build-error-resolver.md +114 -114
- package/agents/chief-of-staff.md +151 -151
- package/agents/code-architect.md +71 -71
- package/agents/code-explorer.md +69 -69
- package/agents/code-reviewer.md +237 -237
- package/agents/code-simplifier.md +47 -47
- package/agents/comment-analyzer.md +45 -45
- package/agents/conversation-analyzer.md +52 -52
- package/agents/cpp-build-resolver.md +90 -90
- package/agents/cpp-reviewer.md +72 -72
- package/agents/csharp-reviewer.md +101 -101
- package/agents/dart-build-resolver.md +201 -201
- package/agents/database-reviewer.md +91 -91
- package/agents/doc-updater.md +107 -107
- package/agents/docs-lookup.md +68 -68
- package/agents/e2e-runner.md +107 -107
- package/agents/flutter-reviewer.md +243 -243
- package/agents/gan-evaluator.md +209 -209
- package/agents/gan-generator.md +131 -131
- package/agents/gan-planner.md +99 -99
- package/agents/get-current-datetime.md +26 -26
- package/agents/go-build-resolver.md +94 -94
- package/agents/go-reviewer.md +76 -76
- package/agents/harness-optimizer.md +35 -35
- package/agents/healthcare-reviewer.md +83 -83
- package/agents/java-build-resolver.md +153 -153
- package/agents/java-reviewer.md +92 -92
- package/agents/kotlin-build-resolver.md +118 -118
- package/agents/kotlin-reviewer.md +159 -159
- package/agents/loop-operator.md +36 -36
- package/agents/opensource-forker.md +198 -198
- package/agents/opensource-packager.md +249 -249
- package/agents/opensource-sanitizer.md +188 -188
- package/agents/performance-optimizer.md +446 -446
- package/agents/planner.md +212 -212
- package/agents/pr-test-analyzer.md +45 -45
- package/agents/python-reviewer.md +98 -98
- package/agents/pytorch-build-resolver.md +120 -120
- package/agents/refactor-cleaner.md +85 -85
- package/agents/rust-build-resolver.md +148 -148
- package/agents/rust-reviewer.md +94 -94
- package/agents/security-reviewer.md +108 -108
- package/agents/seo-specialist.md +59 -59
- package/agents/silent-failure-hunter.md +50 -50
- package/agents/tdd-guide.md +91 -91
- package/agents/type-design-analyzer.md +41 -41
- package/agents/typescript-reviewer.md +112 -112
- package/cli/commands/update.mjs +1 -1
- package/cli/utils/scaffold.mjs +53 -0
- package/docs/rules/agents.md +166 -50
- package/docs/rules/cpp/coding-style.md +44 -44
- package/docs/rules/cpp/hooks.md +39 -39
- package/docs/rules/cpp/patterns.md +51 -51
- package/docs/rules/cpp/security.md +51 -51
- package/docs/rules/cpp/testing.md +44 -44
- package/docs/rules/csharp/coding-style.md +72 -72
- package/docs/rules/csharp/hooks.md +25 -25
- package/docs/rules/csharp/patterns.md +50 -50
- package/docs/rules/csharp/security.md +58 -58
- package/docs/rules/csharp/testing.md +46 -46
- package/docs/rules/dart/coding-style.md +159 -159
- package/docs/rules/dart/hooks.md +66 -66
- package/docs/rules/dart/patterns.md +261 -261
- package/docs/rules/dart/security.md +135 -135
- package/docs/rules/dart/testing.md +215 -215
- package/docs/rules/golang/coding-style.md +32 -32
- package/docs/rules/golang/hooks.md +17 -17
- package/docs/rules/golang/patterns.md +45 -45
- package/docs/rules/golang/security.md +34 -34
- package/docs/rules/golang/testing.md +31 -31
- package/docs/rules/java/coding-style.md +114 -114
- package/docs/rules/java/hooks.md +18 -18
- package/docs/rules/java/patterns.md +146 -146
- package/docs/rules/java/security.md +100 -100
- package/docs/rules/java/testing.md +131 -131
- package/docs/rules/kotlin/coding-style.md +86 -86
- package/docs/rules/kotlin/hooks.md +17 -17
- package/docs/rules/kotlin/patterns.md +146 -146
- package/docs/rules/kotlin/security.md +82 -82
- package/docs/rules/kotlin/testing.md +128 -128
- package/docs/rules/perl/coding-style.md +46 -46
- package/docs/rules/perl/hooks.md +22 -22
- package/docs/rules/perl/patterns.md +76 -76
- package/docs/rules/perl/security.md +69 -69
- package/docs/rules/perl/testing.md +54 -54
- package/docs/rules/php/coding-style.md +40 -40
- package/docs/rules/php/hooks.md +24 -24
- package/docs/rules/php/patterns.md +33 -33
- package/docs/rules/php/security.md +37 -37
- package/docs/rules/php/testing.md +39 -39
- package/docs/rules/python/coding-style.md +42 -42
- package/docs/rules/python/hooks.md +19 -19
- package/docs/rules/python/patterns.md +39 -39
- package/docs/rules/python/security.md +30 -30
- package/docs/rules/python/testing.md +38 -38
- package/docs/rules/rust/coding-style.md +151 -151
- package/docs/rules/rust/hooks.md +16 -16
- package/docs/rules/rust/patterns.md +168 -168
- package/docs/rules/rust/security.md +141 -141
- package/docs/rules/rust/testing.md +154 -154
- package/docs/rules/swift/coding-style.md +47 -47
- package/docs/rules/swift/hooks.md +20 -20
- package/docs/rules/swift/patterns.md +66 -66
- package/docs/rules/swift/security.md +33 -33
- package/docs/rules/swift/testing.md +45 -45
- package/docs/rules/typescript/coding-style.md +199 -199
- package/docs/rules/typescript/hooks.md +22 -22
- package/docs/rules/typescript/patterns.md +52 -52
- package/docs/rules/typescript/security.md +28 -28
- package/docs/rules/typescript/testing.md +18 -18
- package/docs/rules/web/coding-style.md +96 -96
- package/docs/rules/web/design-quality.md +62 -62
- package/docs/rules/web/hooks.md +120 -120
- package/docs/rules/web/patterns.md +79 -79
- package/docs/rules/web/performance.md +64 -64
- package/docs/rules/web/security.md +57 -57
- package/docs/rules/web/testing.md +55 -55
- package/docs/templates/README.md +36 -36
- package/docs/templates/ai-project-final.md +124 -124
- package/docs/templates/ai-project.md +105 -105
- package/docs/templates/api.md +157 -157
- package/docs/templates/bug.md +62 -62
- package/docs/templates/code-review.md +87 -87
- package/docs/templates/generic.md +116 -116
- package/docs/templates/implementation-plan.md +1 -1
- package/docs/templates/meeting.md +68 -68
- package/docs/templates/prd.md +98 -98
- package/docs/templates/ui.md +134 -134
- package/docs/workflow-pipeline.md +11 -10
- package/package.json +40 -39
- package/scripts/hooks/checks/orchestration-artifacts.cjs +28 -23
- package/scripts/hooks/checks/workflow-state.cjs +4 -5
- package/scripts/orchestration/lib/orchestrator.cjs +344 -117
- package/scripts/orchestration/lib/validate.cjs +145 -0
- package/scripts/orchestration/session.cjs +88 -44
- package/skills/SUPERPOWERS-LICENSE +21 -21
- package/skills/ai-ml/fine-tuning-expert/SKILL.md +162 -162
- package/skills/ai-ml/fine-tuning-expert/references/dataset-preparation.md +540 -540
- package/skills/ai-ml/fine-tuning-expert/references/deployment-optimization.md +673 -673
- package/skills/ai-ml/fine-tuning-expert/references/evaluation-metrics.md +597 -597
- package/skills/ai-ml/fine-tuning-expert/references/hyperparameter-tuning.md +565 -565
- package/skills/ai-ml/fine-tuning-expert/references/lora-peft.md +347 -347
- package/skills/ai-ml/ml-pipeline/SKILL.md +159 -159
- package/skills/ai-ml/ml-pipeline/references/experiment-tracking.md +833 -833
- package/skills/ai-ml/ml-pipeline/references/feature-engineering.md +631 -631
- package/skills/ai-ml/ml-pipeline/references/model-validation.md +978 -978
- package/skills/ai-ml/ml-pipeline/references/pipeline-orchestration.md +907 -907
- package/skills/ai-ml/ml-pipeline/references/training-pipelines.md +782 -782
- package/skills/ai-ml/rag-architect/SKILL.md +194 -194
- package/skills/ai-ml/rag-architect/references/chunking-strategies.md +878 -878
- package/skills/ai-ml/rag-architect/references/embedding-models.md +561 -561
- package/skills/ai-ml/rag-architect/references/rag-evaluation.md +833 -833
- package/skills/ai-ml/rag-architect/references/retrieval-optimization.md +795 -795
- package/skills/ai-ml/rag-architect/references/vector-databases.md +589 -589
- package/skills/ai-ml/spark-engineer/SKILL.md +148 -148
- package/skills/ai-ml/spark-engineer/references/partitioning-caching.md +543 -543
- package/skills/ai-ml/spark-engineer/references/performance-tuning.md +544 -544
- package/skills/ai-ml/spark-engineer/references/rdd-operations.md +599 -599
- package/skills/ai-ml/spark-engineer/references/spark-sql-dataframes.md +474 -474
- package/skills/ai-ml/spark-engineer/references/streaming-patterns.md +786 -786
- package/skills/backend/api-designer/SKILL.md +217 -217
- package/skills/backend/api-designer/references/error-handling.md +541 -541
- package/skills/backend/api-designer/references/openapi.md +824 -824
- package/skills/backend/api-designer/references/pagination.md +494 -494
- package/skills/backend/api-designer/references/rest-patterns.md +335 -335
- package/skills/backend/api-designer/references/versioning.md +391 -391
- package/skills/backend/architecture-designer/SKILL.md +117 -117
- package/skills/backend/architecture-designer/references/adr-template.md +116 -116
- package/skills/backend/architecture-designer/references/architecture-patterns.md +111 -111
- package/skills/backend/architecture-designer/references/database-selection.md +102 -102
- package/skills/backend/architecture-designer/references/nfr-checklist.md +112 -112
- package/skills/backend/architecture-designer/references/system-design.md +100 -100
- package/skills/backend/code-documenter/SKILL.md +147 -147
- package/skills/backend/code-documenter/references/api-docs-fastapi-django.md +166 -166
- package/skills/backend/code-documenter/references/api-docs-nestjs-express.md +220 -220
- package/skills/backend/code-documenter/references/coverage-reports.md +125 -125
- package/skills/backend/code-documenter/references/documentation-systems.md +333 -333
- package/skills/backend/code-documenter/references/interactive-api-docs.md +531 -531
- package/skills/backend/code-documenter/references/python-docstrings.md +121 -121
- package/skills/backend/code-documenter/references/typescript-jsdoc.md +145 -145
- package/skills/backend/code-documenter/references/user-guides-tutorials.md +530 -530
- package/skills/backend/debugging-wizard/SKILL.md +105 -105
- package/skills/backend/debugging-wizard/references/common-patterns.md +132 -132
- package/skills/backend/debugging-wizard/references/debugging-tools.md +140 -140
- package/skills/backend/debugging-wizard/references/quick-fixes.md +177 -177
- package/skills/backend/debugging-wizard/references/strategies.md +142 -142
- package/skills/backend/debugging-wizard/references/systematic-debugging.md +367 -367
- package/skills/backend/feature-forge/SKILL.md +98 -98
- package/skills/backend/feature-forge/references/acceptance-criteria.md +104 -104
- package/skills/backend/feature-forge/references/ears-syntax.md +99 -99
- package/skills/backend/feature-forge/references/interview-questions.md +150 -150
- package/skills/backend/feature-forge/references/pre-discovery-subagents.md +54 -54
- package/skills/backend/feature-forge/references/specification-template.md +103 -103
- package/skills/backend/fullstack-guardian/SKILL.md +105 -105
- package/skills/backend/fullstack-guardian/references/api-design-standards.md +307 -307
- package/skills/backend/fullstack-guardian/references/architecture-decisions.md +350 -350
- package/skills/backend/fullstack-guardian/references/backend-patterns.md +237 -237
- package/skills/backend/fullstack-guardian/references/common-patterns.md +134 -134
- package/skills/backend/fullstack-guardian/references/deliverables-checklist.md +354 -354
- package/skills/backend/fullstack-guardian/references/design-template.md +91 -91
- package/skills/backend/fullstack-guardian/references/error-handling.md +135 -135
- package/skills/backend/fullstack-guardian/references/frontend-patterns.md +340 -340
- package/skills/backend/fullstack-guardian/references/integration-patterns.md +333 -333
- package/skills/backend/fullstack-guardian/references/security-checklist.md +106 -106
- package/skills/backend/graphql-architect/SKILL.md +146 -146
- package/skills/backend/graphql-architect/references/federation.md +418 -418
- package/skills/backend/graphql-architect/references/migration-from-rest.md +1141 -1141
- package/skills/backend/graphql-architect/references/resolvers.md +425 -425
- package/skills/backend/graphql-architect/references/schema-design.md +393 -393
- package/skills/backend/graphql-architect/references/security.md +569 -569
- package/skills/backend/graphql-architect/references/subscriptions.md +510 -510
- package/skills/backend/legacy-modernizer/SKILL.md +137 -137
- package/skills/backend/legacy-modernizer/references/legacy-testing.md +381 -381
- package/skills/backend/legacy-modernizer/references/migration-strategies.md +423 -423
- package/skills/backend/legacy-modernizer/references/refactoring-patterns.md +395 -395
- package/skills/backend/legacy-modernizer/references/strangler-fig-pattern.md +281 -281
- package/skills/backend/legacy-modernizer/references/system-assessment.md +487 -487
- package/skills/backend/microservices-architect/SKILL.md +164 -164
- package/skills/backend/microservices-architect/references/communication.md +499 -499
- package/skills/backend/microservices-architect/references/data.md +721 -721
- package/skills/backend/microservices-architect/references/decomposition.md +344 -344
- package/skills/backend/microservices-architect/references/observability.md +805 -805
- package/skills/backend/microservices-architect/references/patterns.md +603 -603
- package/skills/database/database-optimizer/SKILL.md +147 -147
- package/skills/database/database-optimizer/references/index-strategies.md +331 -331
- package/skills/database/database-optimizer/references/monitoring-analysis.md +501 -501
- package/skills/database/database-optimizer/references/mysql-tuning.md +452 -452
- package/skills/database/database-optimizer/references/postgresql-tuning.md +413 -413
- package/skills/database/database-optimizer/references/query-optimization.md +251 -251
- package/skills/database/postgres-pro/SKILL.md +152 -152
- package/skills/database/postgres-pro/references/extensions.md +404 -404
- package/skills/database/postgres-pro/references/jsonb.md +321 -321
- package/skills/database/postgres-pro/references/maintenance.md +481 -481
- package/skills/database/postgres-pro/references/performance.md +265 -265
- package/skills/database/postgres-pro/references/replication.md +446 -446
- package/skills/database/sql-pro/SKILL.md +129 -129
- package/skills/database/sql-pro/references/database-design.md +402 -402
- package/skills/database/sql-pro/references/dialect-differences.md +419 -419
- package/skills/database/sql-pro/references/optimization.md +384 -384
- package/skills/database/sql-pro/references/query-patterns.md +285 -285
- package/skills/database/sql-pro/references/window-functions.md +328 -328
- package/skills/dotnet/csharp-developer/SKILL.md +125 -125
- package/skills/dotnet/csharp-developer/references/aspnet-core.md +394 -394
- package/skills/dotnet/csharp-developer/references/blazor.md +553 -553
- package/skills/dotnet/csharp-developer/references/entity-framework.md +409 -409
- package/skills/dotnet/csharp-developer/references/modern-csharp.md +248 -248
- package/skills/dotnet/csharp-developer/references/performance.md +498 -498
- package/skills/dotnet/dotnet-core-expert/SKILL.md +138 -138
- package/skills/dotnet/dotnet-core-expert/references/authentication.md +546 -546
- package/skills/dotnet/dotnet-core-expert/references/clean-architecture.md +455 -455
- package/skills/dotnet/dotnet-core-expert/references/cloud-native.md +548 -548
- package/skills/dotnet/dotnet-core-expert/references/entity-framework.md +440 -440
- package/skills/dotnet/dotnet-core-expert/references/minimal-apis.md +319 -319
- package/skills/frontend/angular-architect/SKILL.md +152 -152
- package/skills/frontend/angular-architect/references/components.md +297 -297
- package/skills/frontend/angular-architect/references/ngrx.md +401 -401
- package/skills/frontend/angular-architect/references/routing.md +361 -361
- package/skills/frontend/angular-architect/references/rxjs.md +319 -319
- package/skills/frontend/angular-architect/references/testing.md +405 -405
- package/skills/frontend/design-commands/design.md +91 -91
- package/skills/frontend/design-commands/handoff.md +97 -97
- package/skills/frontend/design-commands/prototype.md +120 -120
- package/skills/frontend/design-commands/spec.md +160 -160
- package/skills/frontend/design-commands/style.md +78 -78
- package/skills/frontend/flutter-expert/SKILL.md +138 -138
- package/skills/frontend/flutter-expert/references/bloc-state.md +259 -259
- package/skills/frontend/flutter-expert/references/gorouter-navigation.md +119 -119
- package/skills/frontend/flutter-expert/references/performance.md +99 -99
- package/skills/frontend/flutter-expert/references/project-structure.md +118 -118
- package/skills/frontend/flutter-expert/references/riverpod-state.md +130 -130
- package/skills/frontend/flutter-expert/references/widget-patterns.md +123 -123
- package/skills/frontend/nextjs-developer/SKILL.md +143 -143
- package/skills/frontend/nextjs-developer/references/app-router.md +311 -311
- package/skills/frontend/nextjs-developer/references/data-fetching.md +482 -482
- package/skills/frontend/nextjs-developer/references/deployment.md +545 -545
- package/skills/frontend/nextjs-developer/references/server-actions.md +462 -462
- package/skills/frontend/nextjs-developer/references/server-components.md +384 -384
- package/skills/frontend/react-expert/SKILL.md +149 -149
- package/skills/frontend/react-expert/references/hooks-patterns.md +162 -162
- package/skills/frontend/react-expert/references/migration-class-to-modern.md +1119 -1119
- package/skills/frontend/react-expert/references/performance.md +168 -168
- package/skills/frontend/react-expert/references/react-19-features.md +174 -174
- package/skills/frontend/react-expert/references/server-components.md +143 -143
- package/skills/frontend/react-expert/references/state-management.md +171 -171
- package/skills/frontend/react-expert/references/testing-react.md +174 -174
- package/skills/frontend/react-native-expert/SKILL.md +185 -185
- package/skills/frontend/react-native-expert/references/expo-router.md +187 -187
- package/skills/frontend/react-native-expert/references/list-optimization.md +204 -204
- package/skills/frontend/react-native-expert/references/platform-handling.md +188 -188
- package/skills/frontend/react-native-expert/references/project-structure.md +171 -171
- package/skills/frontend/react-native-expert/references/storage-hooks.md +173 -173
- package/skills/frontend/senior-frontend/SKILL.md +477 -477
- package/skills/frontend/senior-frontend/references/frontend_best_practices.md +806 -806
- package/skills/frontend/senior-frontend/references/nextjs_optimization_guide.md +724 -724
- package/skills/frontend/senior-frontend/references/react_patterns.md +746 -746
- package/skills/frontend/senior-frontend/scripts/bundle_analyzer.py +407 -407
- package/skills/frontend/senior-frontend/scripts/component_generator.py +329 -329
- package/skills/frontend/senior-frontend/scripts/frontend_scaffolder.py +1005 -1005
- package/skills/frontend/ui-ux-pro-max/SKILL.md +386 -386
- package/skills/frontend/ui-ux-pro-max/data/charts.csv +26 -26
- package/skills/frontend/ui-ux-pro-max/data/colors.csv +97 -97
- package/skills/frontend/ui-ux-pro-max/data/icons.csv +101 -101
- package/skills/frontend/ui-ux-pro-max/data/landing.csv +31 -31
- package/skills/frontend/ui-ux-pro-max/data/products.csv +96 -96
- package/skills/frontend/ui-ux-pro-max/data/react-performance.csv +45 -45
- package/skills/frontend/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/skills/frontend/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/skills/frontend/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/skills/frontend/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/skills/frontend/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/skills/frontend/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/skills/frontend/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/skills/frontend/ui-ux-pro-max/data/styles.csv +68 -68
- package/skills/frontend/ui-ux-pro-max/data/typography.csv +57 -57
- package/skills/frontend/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
- package/skills/frontend/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/skills/frontend/ui-ux-pro-max/data/web-interface.csv +31 -31
- package/skills/frontend/ui-ux-pro-max/scripts/core.py +253 -253
- package/skills/frontend/ui-ux-pro-max/scripts/design_system.py +1067 -1067
- package/skills/frontend/ui-ux-pro-max/scripts/search.py +114 -114
- package/skills/frontend/vue-expert/SKILL.md +98 -98
- package/skills/frontend/vue-expert/references/build-tooling.md +480 -480
- package/skills/frontend/vue-expert/references/components.md +448 -448
- package/skills/frontend/vue-expert/references/composition-api.md +299 -299
- package/skills/frontend/vue-expert/references/mobile-hybrid.md +636 -636
- package/skills/frontend/vue-expert/references/nuxt.md +669 -669
- package/skills/frontend/vue-expert/references/state-management.md +449 -449
- package/skills/frontend/vue-expert/references/typescript.md +584 -584
- package/skills/frontend/vue-expert-js/SKILL.md +167 -167
- package/skills/frontend/vue-expert-js/references/component-architecture.md +219 -219
- package/skills/frontend/vue-expert-js/references/composables-patterns.md +183 -183
- package/skills/frontend/vue-expert-js/references/jsdoc-typing.md +535 -535
- package/skills/frontend/vue-expert-js/references/state-management.md +249 -249
- package/skills/frontend/vue-expert-js/references/testing-patterns.md +237 -237
- package/skills/go-rust-cpp/cpp-pro/SKILL.md +115 -115
- package/skills/go-rust-cpp/cpp-pro/references/build-tooling.md +440 -440
- package/skills/go-rust-cpp/cpp-pro/references/concurrency.md +437 -437
- package/skills/go-rust-cpp/cpp-pro/references/memory-performance.md +397 -397
- package/skills/go-rust-cpp/cpp-pro/references/modern-cpp.md +304 -304
- package/skills/go-rust-cpp/cpp-pro/references/templates.md +357 -357
- package/skills/go-rust-cpp/golang-pro/SKILL.md +122 -122
- package/skills/go-rust-cpp/golang-pro/references/concurrency.md +329 -329
- package/skills/go-rust-cpp/golang-pro/references/generics.md +442 -442
- package/skills/go-rust-cpp/golang-pro/references/interfaces.md +432 -432
- package/skills/go-rust-cpp/golang-pro/references/project-structure.md +477 -477
- package/skills/go-rust-cpp/golang-pro/references/testing.md +451 -451
- package/skills/go-rust-cpp/rust-engineer/SKILL.md +167 -167
- package/skills/go-rust-cpp/rust-engineer/references/async.md +458 -458
- package/skills/go-rust-cpp/rust-engineer/references/error-handling.md +334 -334
- package/skills/go-rust-cpp/rust-engineer/references/ownership.md +278 -278
- package/skills/go-rust-cpp/rust-engineer/references/testing.md +470 -470
- package/skills/go-rust-cpp/rust-engineer/references/traits.md +413 -413
- package/skills/infra/cli-developer/SKILL.md +113 -113
- package/skills/infra/cli-developer/references/design-patterns.md +221 -221
- package/skills/infra/cli-developer/references/go-cli.md +540 -540
- package/skills/infra/cli-developer/references/node-cli.md +383 -383
- package/skills/infra/cli-developer/references/python-cli.md +422 -422
- package/skills/infra/cli-developer/references/ux-patterns.md +448 -448
- package/skills/infra/cloud-architect/SKILL.md +216 -216
- package/skills/infra/cloud-architect/references/aws.md +394 -394
- package/skills/infra/cloud-architect/references/azure.md +562 -562
- package/skills/infra/cloud-architect/references/cost.md +582 -582
- package/skills/infra/cloud-architect/references/gcp.md +633 -633
- package/skills/infra/cloud-architect/references/multi-cloud.md +483 -483
- package/skills/infra/devops-engineer/SKILL.md +144 -144
- package/skills/infra/devops-engineer/references/deployment-strategies.md +241 -241
- package/skills/infra/devops-engineer/references/docker-patterns.md +113 -113
- package/skills/infra/devops-engineer/references/github-actions.md +139 -139
- package/skills/infra/devops-engineer/references/incident-response.md +331 -331
- package/skills/infra/devops-engineer/references/kubernetes.md +154 -154
- package/skills/infra/devops-engineer/references/platform-engineering.md +417 -417
- package/skills/infra/devops-engineer/references/release-automation.md +527 -527
- package/skills/infra/devops-engineer/references/terraform-iac.md +141 -141
- package/skills/infra/kubernetes-specialist/SKILL.md +241 -241
- package/skills/infra/kubernetes-specialist/references/configuration.md +452 -452
- package/skills/infra/kubernetes-specialist/references/cost-optimization.md +458 -458
- package/skills/infra/kubernetes-specialist/references/custom-operators.md +563 -563
- package/skills/infra/kubernetes-specialist/references/gitops.md +530 -530
- package/skills/infra/kubernetes-specialist/references/helm-charts.md +912 -912
- package/skills/infra/kubernetes-specialist/references/multi-cluster.md +507 -507
- package/skills/infra/kubernetes-specialist/references/networking.md +447 -447
- package/skills/infra/kubernetes-specialist/references/service-mesh.md +459 -459
- package/skills/infra/kubernetes-specialist/references/storage.md +535 -535
- package/skills/infra/kubernetes-specialist/references/troubleshooting.md +414 -414
- package/skills/infra/kubernetes-specialist/references/workloads.md +377 -377
- package/skills/infra/mcp-developer/SKILL.md +143 -143
- package/skills/infra/mcp-developer/references/protocol.md +244 -244
- package/skills/infra/mcp-developer/references/python-sdk.md +367 -367
- package/skills/infra/mcp-developer/references/resources.md +554 -554
- package/skills/infra/mcp-developer/references/tools.md +480 -480
- package/skills/infra/mcp-developer/references/typescript-sdk.md +350 -350
- package/skills/infra/monitoring-expert/SKILL.md +176 -176
- package/skills/infra/monitoring-expert/references/alerting-rules.md +141 -141
- package/skills/infra/monitoring-expert/references/application-profiling.md +331 -331
- package/skills/infra/monitoring-expert/references/capacity-planning.md +344 -344
- package/skills/infra/monitoring-expert/references/dashboards.md +126 -126
- package/skills/infra/monitoring-expert/references/opentelemetry.md +123 -123
- package/skills/infra/monitoring-expert/references/performance-testing.md +269 -269
- package/skills/infra/monitoring-expert/references/prometheus-metrics.md +136 -136
- package/skills/infra/monitoring-expert/references/structured-logging.md +142 -142
- package/skills/infra/sre-engineer/SKILL.md +181 -181
- package/skills/infra/sre-engineer/references/automation-toil.md +492 -492
- package/skills/infra/sre-engineer/references/error-budget-policy.md +334 -334
- package/skills/infra/sre-engineer/references/incident-chaos.md +576 -576
- package/skills/infra/sre-engineer/references/monitoring-alerting.md +424 -424
- package/skills/infra/sre-engineer/references/slo-sli-management.md +238 -238
- package/skills/infra/terraform-engineer/SKILL.md +143 -143
- package/skills/infra/terraform-engineer/references/best-practices.md +583 -583
- package/skills/infra/terraform-engineer/references/module-patterns.md +297 -297
- package/skills/infra/terraform-engineer/references/providers.md +452 -452
- package/skills/infra/terraform-engineer/references/state-management.md +371 -371
- package/skills/infra/terraform-engineer/references/testing.md +486 -486
- package/skills/infra/websocket-engineer/SKILL.md +168 -168
- package/skills/infra/websocket-engineer/references/alternatives.md +391 -391
- package/skills/infra/websocket-engineer/references/patterns.md +400 -400
- package/skills/infra/websocket-engineer/references/protocol.md +195 -195
- package/skills/infra/websocket-engineer/references/scaling.md +333 -333
- package/skills/infra/websocket-engineer/references/security.md +474 -474
- package/skills/java/java-architect/SKILL.md +132 -132
- package/skills/java/java-architect/references/jpa-optimization.md +393 -393
- package/skills/java/java-architect/references/reactive-webflux.md +356 -356
- package/skills/java/java-architect/references/spring-boot-setup.md +269 -269
- package/skills/java/java-architect/references/spring-security.md +445 -445
- package/skills/java/java-architect/references/testing-patterns.md +500 -500
- package/skills/java/kotlin-specialist/SKILL.md +147 -147
- package/skills/java/kotlin-specialist/references/android-compose.md +419 -419
- package/skills/java/kotlin-specialist/references/coroutines-flow.md +276 -276
- package/skills/java/kotlin-specialist/references/dsl-idioms.md +421 -421
- package/skills/java/kotlin-specialist/references/ktor-server.md +426 -426
- package/skills/java/kotlin-specialist/references/multiplatform-kmp.md +380 -380
- package/skills/java/spring-boot-engineer/SKILL.md +195 -195
- package/skills/java/spring-boot-engineer/references/cloud.md +498 -498
- package/skills/java/spring-boot-engineer/references/data.md +381 -381
- package/skills/java/spring-boot-engineer/references/security.md +459 -459
- package/skills/java/spring-boot-engineer/references/testing.md +545 -545
- package/skills/java/spring-boot-engineer/references/web.md +295 -295
- package/skills/javascript/javascript-pro/SKILL.md +132 -132
- package/skills/javascript/javascript-pro/references/async-patterns.md +334 -334
- package/skills/javascript/javascript-pro/references/browser-apis.md +398 -398
- package/skills/javascript/javascript-pro/references/modern-syntax.md +272 -272
- package/skills/javascript/javascript-pro/references/modules.md +357 -357
- package/skills/javascript/javascript-pro/references/node-essentials.md +471 -471
- package/skills/javascript/nestjs-expert/SKILL.md +206 -206
- package/skills/javascript/nestjs-expert/references/authentication.md +166 -166
- package/skills/javascript/nestjs-expert/references/controllers-routing.md +111 -111
- package/skills/javascript/nestjs-expert/references/dtos-validation.md +153 -153
- package/skills/javascript/nestjs-expert/references/migration-from-express.md +1237 -1237
- package/skills/javascript/nestjs-expert/references/services-di.md +140 -140
- package/skills/javascript/nestjs-expert/references/testing-patterns.md +186 -186
- package/skills/javascript/typescript-pro/SKILL.md +145 -145
- package/skills/javascript/typescript-pro/references/advanced-types.md +259 -259
- package/skills/javascript/typescript-pro/references/configuration.md +445 -445
- package/skills/javascript/typescript-pro/references/patterns.md +484 -484
- package/skills/javascript/typescript-pro/references/type-guards.md +352 -352
- package/skills/javascript/typescript-pro/references/utility-types.md +329 -329
- package/skills/php/laravel-specialist/SKILL.md +262 -262
- package/skills/php/laravel-specialist/references/eloquent.md +351 -351
- package/skills/php/laravel-specialist/references/livewire.md +512 -512
- package/skills/php/laravel-specialist/references/queues.md +423 -423
- package/skills/php/laravel-specialist/references/routing.md +362 -362
- package/skills/php/laravel-specialist/references/testing.md +522 -522
- package/skills/php/php-pro/SKILL.md +206 -206
- package/skills/php/php-pro/references/async-patterns.md +412 -412
- package/skills/php/php-pro/references/laravel-patterns.md +377 -377
- package/skills/php/php-pro/references/modern-php-features.md +323 -323
- package/skills/php/php-pro/references/symfony-patterns.md +466 -466
- package/skills/php/php-pro/references/testing-quality.md +466 -466
- package/skills/product/competitive-analysis/SKILL.md +257 -257
- package/skills/product/meeting-notes/SKILL.md +266 -266
- package/skills/product/prd-template/SKILL.md +150 -150
- package/skills/product/stakeholder-update/SKILL.md +225 -225
- package/skills/product/user-research-synthesis/SKILL.md +235 -235
- package/skills/python/django-expert/SKILL.md +162 -162
- package/skills/python/django-expert/references/authentication.md +145 -145
- package/skills/python/django-expert/references/drf-serializers.md +148 -148
- package/skills/python/django-expert/references/models-orm.md +151 -151
- package/skills/python/django-expert/references/testing-django.md +204 -204
- package/skills/python/django-expert/references/viewsets-views.md +153 -153
- package/skills/python/fastapi-expert/SKILL.md +185 -185
- package/skills/python/fastapi-expert/references/async-sqlalchemy.md +146 -146
- package/skills/python/fastapi-expert/references/authentication.md +159 -159
- package/skills/python/fastapi-expert/references/endpoints-routing.md +142 -142
- package/skills/python/fastapi-expert/references/migration-from-django.md +996 -996
- package/skills/python/fastapi-expert/references/pydantic-v2.md +135 -135
- package/skills/python/fastapi-expert/references/testing-async.md +159 -159
- package/skills/python/pandas-pro/SKILL.md +178 -178
- package/skills/python/pandas-pro/references/aggregation-groupby.md +545 -545
- package/skills/python/pandas-pro/references/data-cleaning.md +500 -500
- package/skills/python/pandas-pro/references/dataframe-operations.md +420 -420
- package/skills/python/pandas-pro/references/merging-joining.md +596 -596
- package/skills/python/pandas-pro/references/performance-optimization.md +597 -597
- package/skills/python/python-pro/SKILL.md +177 -177
- package/skills/python/python-pro/references/async-patterns.md +356 -356
- package/skills/python/python-pro/references/packaging.md +460 -460
- package/skills/python/python-pro/references/standard-library.md +378 -378
- package/skills/python/python-pro/references/testing.md +404 -404
- package/skills/python/python-pro/references/type-system.md +290 -290
- package/skills/quality/chaos-engineer/SKILL.md +182 -182
- package/skills/quality/chaos-engineer/references/chaos-tools.md +511 -511
- package/skills/quality/chaos-engineer/references/experiment-design.md +229 -229
- package/skills/quality/chaos-engineer/references/game-days.md +434 -434
- package/skills/quality/chaos-engineer/references/infrastructure-chaos.md +348 -348
- package/skills/quality/chaos-engineer/references/kubernetes-chaos.md +432 -432
- package/skills/quality/code-reviewer/SKILL.md +119 -119
- package/skills/quality/code-reviewer/references/common-issues.md +142 -142
- package/skills/quality/code-reviewer/references/feedback-examples.md +144 -144
- package/skills/quality/code-reviewer/references/receiving-feedback.md +238 -238
- package/skills/quality/code-reviewer/references/report-template.md +109 -109
- package/skills/quality/code-reviewer/references/review-checklist.md +88 -88
- package/skills/quality/code-reviewer/references/spec-compliance-review.md +258 -258
- package/skills/quality/playwright-expert/SKILL.md +169 -169
- package/skills/quality/playwright-expert/references/api-mocking.md +140 -140
- package/skills/quality/playwright-expert/references/configuration.md +155 -155
- package/skills/quality/playwright-expert/references/debugging-flaky.md +150 -150
- package/skills/quality/playwright-expert/references/page-object-model.md +152 -152
- package/skills/quality/playwright-expert/references/selectors-locators.md +119 -119
- package/skills/quality/secure-code-guardian/SKILL.md +191 -191
- package/skills/quality/secure-code-guardian/references/authentication.md +136 -136
- package/skills/quality/secure-code-guardian/references/input-validation.md +146 -146
- package/skills/quality/secure-code-guardian/references/owasp-prevention.md +135 -135
- package/skills/quality/secure-code-guardian/references/security-headers.md +133 -133
- package/skills/quality/secure-code-guardian/references/xss-csrf.md +157 -157
- package/skills/quality/security-reviewer/SKILL.md +103 -103
- package/skills/quality/security-reviewer/references/infrastructure-security.md +268 -268
- package/skills/quality/security-reviewer/references/penetration-testing.md +268 -268
- package/skills/quality/security-reviewer/references/report-template.md +170 -170
- package/skills/quality/security-reviewer/references/sast-tools.md +117 -117
- package/skills/quality/security-reviewer/references/secret-scanning.md +125 -125
- package/skills/quality/security-reviewer/references/vulnerability-patterns.md +152 -152
- package/skills/quality/senior-qa/README.md +196 -196
- package/skills/quality/senior-qa/SKILL.md +399 -399
- package/skills/quality/senior-qa/references/qa_best_practices.md +964 -964
- package/skills/quality/senior-qa/references/test_automation_patterns.md +1009 -1009
- package/skills/quality/senior-qa/references/testing_strategies.md +649 -649
- package/skills/quality/senior-qa/scripts/coverage_analyzer.py +836 -836
- package/skills/quality/senior-qa/scripts/e2e_test_scaffolder.py +820 -820
- package/skills/quality/senior-qa/scripts/test_suite_generator.py +605 -605
- package/skills/quality/tdd-guide/HOW_TO_USE.md +313 -313
- package/skills/quality/tdd-guide/README.md +680 -680
- package/skills/quality/tdd-guide/SKILL.md +122 -122
- package/skills/quality/tdd-guide/assets/expected_output.json +77 -77
- package/skills/quality/tdd-guide/assets/sample_input_python.json +39 -39
- package/skills/quality/tdd-guide/assets/sample_input_typescript.json +36 -36
- package/skills/quality/tdd-guide/references/ci-integration.md +195 -195
- package/skills/quality/tdd-guide/references/framework-guide.md +206 -206
- package/skills/quality/tdd-guide/references/tdd-best-practices.md +128 -128
- package/skills/quality/tdd-guide/scripts/coverage_analyzer.py +434 -434
- package/skills/quality/tdd-guide/scripts/fixture_generator.py +440 -440
- package/skills/quality/tdd-guide/scripts/format_detector.py +384 -384
- package/skills/quality/tdd-guide/scripts/framework_adapter.py +428 -428
- package/skills/quality/tdd-guide/scripts/metrics_calculator.py +456 -456
- package/skills/quality/tdd-guide/scripts/output_formatter.py +354 -354
- package/skills/quality/tdd-guide/scripts/tdd_workflow.py +474 -474
- package/skills/quality/tdd-guide/scripts/test_generator.py +438 -438
- package/skills/quality/test-master/SKILL.md +94 -94
- package/skills/quality/test-master/references/automation-frameworks.md +294 -294
- package/skills/quality/test-master/references/e2e-testing.md +128 -128
- package/skills/quality/test-master/references/integration-testing.md +120 -120
- package/skills/quality/test-master/references/performance-testing.md +118 -118
- package/skills/quality/test-master/references/qa-methodology.md +247 -247
- package/skills/quality/test-master/references/security-testing.md +127 -127
- package/skills/quality/test-master/references/tdd-iron-laws.md +174 -174
- package/skills/quality/test-master/references/test-reports.md +104 -104
- package/skills/quality/test-master/references/testing-anti-patterns.md +231 -231
- package/skills/quality/test-master/references/unit-testing.md +113 -113
- package/skills/ruby/rails-expert/SKILL.md +154 -154
- package/skills/ruby/rails-expert/references/active-record.md +244 -244
- package/skills/ruby/rails-expert/references/api-development.md +401 -401
- package/skills/ruby/rails-expert/references/background-jobs.md +272 -272
- package/skills/ruby/rails-expert/references/hotwire-turbo.md +228 -228
- package/skills/ruby/rails-expert/references/rspec-testing.md +367 -367
- package/skills/swift/swift-expert/SKILL.md +163 -163
- package/skills/swift/swift-expert/references/async-concurrency.md +360 -360
- package/skills/swift/swift-expert/references/memory-performance.md +377 -377
- package/skills/swift/swift-expert/references/protocol-oriented.md +354 -354
- package/skills/swift/swift-expert/references/swiftui-patterns.md +291 -291
- package/skills/swift/swift-expert/references/testing-patterns.md +399 -399
- package/skills/workflow/brainstorming/SKILL.md +164 -164
- package/skills/workflow/brainstorming/scripts/frame-template.html +214 -214
- package/skills/workflow/brainstorming/scripts/helper.js +88 -88
- package/skills/workflow/brainstorming/scripts/server.cjs +354 -354
- package/skills/workflow/brainstorming/scripts/start-server.sh +148 -148
- package/skills/workflow/brainstorming/scripts/stop-server.sh +56 -56
- package/skills/workflow/brainstorming/spec-document-reviewer-prompt.md +49 -49
- package/skills/workflow/brainstorming/visual-companion.md +287 -287
- package/skills/workflow/documentation/SKILL.md +45 -45
- package/skills/workflow/entropy-management/SKILL.md +115 -115
- package/skills/workflow/executing-plans/SKILL.md +70 -70
- package/skills/workflow/finishing-a-development-branch/SKILL.md +200 -200
- package/skills/workflow/receiving-code-review/SKILL.md +213 -213
- package/skills/workflow/requesting-code-review/SKILL.md +105 -105
- package/skills/workflow/requesting-code-review/code-reviewer.md +146 -146
- package/skills/workflow/requirement-engineering/SKILL.md +111 -111
- package/skills/workflow/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/workflow/systematic-debugging/SKILL.md +296 -296
- package/skills/workflow/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/workflow/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/workflow/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/workflow/systematic-debugging/find-polluter.sh +63 -63
- package/skills/workflow/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/workflow/systematic-debugging/test-academic.md +14 -14
- package/skills/workflow/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/workflow/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/workflow/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/workflow/using-git-worktrees/SKILL.md +218 -218
- package/skills/workflow/verification-before-completion/SKILL.md +139 -139
- package/skills/workflow/writing-plans/SKILL.md +151 -151
- package/skills/workflow/writing-plans/plan-document-reviewer-prompt.md +49 -49
- package/skills/workflow/writing-skills/SKILL.md +655 -655
- package/skills/workflow/writing-skills/anthropic-best-practices.md +1150 -1150
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
- package/skills/workflow/writing-skills/persuasion-principles.md +187 -187
- package/skills/workflow/writing-skills/render-graphs.js +168 -168
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +384 -384
|
@@ -1,409 +1,409 @@
|
|
|
1
|
-
# Entity Framework Core Patterns
|
|
2
|
-
|
|
3
|
-
## DbContext Setup
|
|
4
|
-
|
|
5
|
-
```csharp
|
|
6
|
-
using Microsoft.EntityFrameworkCore;
|
|
7
|
-
|
|
8
|
-
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
|
|
9
|
-
{
|
|
10
|
-
public DbSet<Product> Products => Set<Product>();
|
|
11
|
-
public DbSet<Category> Categories => Set<Category>();
|
|
12
|
-
public DbSet<Order> Orders => Set<Order>();
|
|
13
|
-
|
|
14
|
-
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
15
|
-
{
|
|
16
|
-
base.OnModelCreating(modelBuilder);
|
|
17
|
-
|
|
18
|
-
// Apply all configurations from assembly
|
|
19
|
-
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
|
|
20
|
-
|
|
21
|
-
// Global query filters
|
|
22
|
-
modelBuilder.Entity<Product>()
|
|
23
|
-
.HasQueryFilter(p => !p.IsDeleted);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Configuration class (recommended)
|
|
28
|
-
public class ProductConfiguration : IEntityTypeConfiguration<Product>
|
|
29
|
-
{
|
|
30
|
-
public void Configure(EntityTypeBuilder<Product> builder)
|
|
31
|
-
{
|
|
32
|
-
builder.ToTable("Products");
|
|
33
|
-
|
|
34
|
-
builder.HasKey(p => p.Id);
|
|
35
|
-
|
|
36
|
-
builder.Property(p => p.Name)
|
|
37
|
-
.IsRequired()
|
|
38
|
-
.HasMaxLength(200);
|
|
39
|
-
|
|
40
|
-
builder.Property(p => p.Price)
|
|
41
|
-
.HasPrecision(18, 2);
|
|
42
|
-
|
|
43
|
-
builder.HasIndex(p => p.Sku)
|
|
44
|
-
.IsUnique();
|
|
45
|
-
|
|
46
|
-
// Relationships
|
|
47
|
-
builder.HasOne(p => p.Category)
|
|
48
|
-
.WithMany(c => c.Products)
|
|
49
|
-
.HasForeignKey(p => p.CategoryId)
|
|
50
|
-
.OnDelete(DeleteBehavior.Restrict);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Entity Models
|
|
56
|
-
|
|
57
|
-
```csharp
|
|
58
|
-
// Base entity
|
|
59
|
-
public abstract class BaseEntity
|
|
60
|
-
{
|
|
61
|
-
public int Id { get; set; }
|
|
62
|
-
public DateTime CreatedAt { get; set; }
|
|
63
|
-
public DateTime? UpdatedAt { get; set; }
|
|
64
|
-
public bool IsDeleted { get; set; }
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Product entity
|
|
68
|
-
public class Product : BaseEntity
|
|
69
|
-
{
|
|
70
|
-
public required string Name { get; set; }
|
|
71
|
-
public required string Sku { get; set; }
|
|
72
|
-
public decimal Price { get; set; }
|
|
73
|
-
public string? Description { get; set; }
|
|
74
|
-
|
|
75
|
-
// Navigation properties
|
|
76
|
-
public int CategoryId { get; set; }
|
|
77
|
-
public Category Category { get; set; } = null!;
|
|
78
|
-
|
|
79
|
-
public ICollection<OrderItem> OrderItems { get; set; } = [];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Value objects (owned types)
|
|
83
|
-
public class Address
|
|
84
|
-
{
|
|
85
|
-
public required string Street { get; init; }
|
|
86
|
-
public required string City { get; init; }
|
|
87
|
-
public required string Country { get; init; }
|
|
88
|
-
public required string PostalCode { get; init; }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
public class Order : BaseEntity
|
|
92
|
-
{
|
|
93
|
-
public required string OrderNumber { get; set; }
|
|
94
|
-
public Address ShippingAddress { get; set; } = null!;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Configuration for owned type
|
|
98
|
-
builder.OwnsOne(o => o.ShippingAddress, address =>
|
|
99
|
-
{
|
|
100
|
-
address.Property(a => a.Street).HasMaxLength(200);
|
|
101
|
-
address.Property(a => a.City).HasMaxLength(100);
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Repository Pattern
|
|
106
|
-
|
|
107
|
-
```csharp
|
|
108
|
-
public interface IRepository<T> where T : BaseEntity
|
|
109
|
-
{
|
|
110
|
-
Task<T?> GetByIdAsync(int id, CancellationToken ct = default);
|
|
111
|
-
Task<List<T>> GetAllAsync(CancellationToken ct = default);
|
|
112
|
-
Task<T> AddAsync(T entity, CancellationToken ct = default);
|
|
113
|
-
Task UpdateAsync(T entity, CancellationToken ct = default);
|
|
114
|
-
Task DeleteAsync(int id, CancellationToken ct = default);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public class Repository<T>(AppDbContext context) : IRepository<T> where T : BaseEntity
|
|
118
|
-
{
|
|
119
|
-
private readonly DbSet<T> _dbSet = context.Set<T>();
|
|
120
|
-
|
|
121
|
-
public async Task<T?> GetByIdAsync(int id, CancellationToken ct = default)
|
|
122
|
-
{
|
|
123
|
-
return await _dbSet.FindAsync([id], cancellationToken: ct);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
public async Task<List<T>> GetAllAsync(CancellationToken ct = default)
|
|
127
|
-
{
|
|
128
|
-
return await _dbSet.AsNoTracking().ToListAsync(ct);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
public async Task<T> AddAsync(T entity, CancellationToken ct = default)
|
|
132
|
-
{
|
|
133
|
-
entity.CreatedAt = DateTime.UtcNow;
|
|
134
|
-
await _dbSet.AddAsync(entity, ct);
|
|
135
|
-
await context.SaveChangesAsync(ct);
|
|
136
|
-
return entity;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
public async Task UpdateAsync(T entity, CancellationToken ct = default)
|
|
140
|
-
{
|
|
141
|
-
entity.UpdatedAt = DateTime.UtcNow;
|
|
142
|
-
_dbSet.Update(entity);
|
|
143
|
-
await context.SaveChangesAsync(ct);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
public async Task DeleteAsync(int id, CancellationToken ct = default)
|
|
147
|
-
{
|
|
148
|
-
var entity = await GetByIdAsync(id, ct);
|
|
149
|
-
if (entity is not null)
|
|
150
|
-
{
|
|
151
|
-
entity.IsDeleted = true;
|
|
152
|
-
await UpdateAsync(entity, ct);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Query Optimization
|
|
159
|
-
|
|
160
|
-
```csharp
|
|
161
|
-
public class ProductRepository(AppDbContext context)
|
|
162
|
-
{
|
|
163
|
-
// AsNoTracking for read-only queries
|
|
164
|
-
public async Task<List<ProductDto>> GetProductsAsync(CancellationToken ct = default)
|
|
165
|
-
{
|
|
166
|
-
return await context.Products
|
|
167
|
-
.AsNoTracking()
|
|
168
|
-
.Select(p => new ProductDto
|
|
169
|
-
{
|
|
170
|
-
Id = p.Id,
|
|
171
|
-
Name = p.Name,
|
|
172
|
-
Price = p.Price
|
|
173
|
-
})
|
|
174
|
-
.ToListAsync(ct);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Include related data (eager loading)
|
|
178
|
-
public async Task<Product?> GetProductWithCategoryAsync(int id, CancellationToken ct = default)
|
|
179
|
-
{
|
|
180
|
-
return await context.Products
|
|
181
|
-
.Include(p => p.Category)
|
|
182
|
-
.FirstOrDefaultAsync(p => p.Id == id, ct);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Split queries for collections
|
|
186
|
-
public async Task<Order?> GetOrderWithItemsAsync(int id, CancellationToken ct = default)
|
|
187
|
-
{
|
|
188
|
-
return await context.Orders
|
|
189
|
-
.Include(o => o.OrderItems)
|
|
190
|
-
.ThenInclude(oi => oi.Product)
|
|
191
|
-
.AsSplitQuery() // Prevents cartesian explosion
|
|
192
|
-
.FirstOrDefaultAsync(o => o.Id == id, ct);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Filtered includes (.NET 5+)
|
|
196
|
-
public async Task<Category?> GetCategoryWithActiveProducts(
|
|
197
|
-
int id,
|
|
198
|
-
CancellationToken ct = default)
|
|
199
|
-
{
|
|
200
|
-
return await context.Categories
|
|
201
|
-
.Include(c => c.Products.Where(p => p.Price > 0))
|
|
202
|
-
.FirstOrDefaultAsync(c => c.Id == id, ct);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Projection for performance
|
|
206
|
-
public async Task<List<ProductSummaryDto>> GetProductSummariesAsync(
|
|
207
|
-
CancellationToken ct = default)
|
|
208
|
-
{
|
|
209
|
-
return await context.Products
|
|
210
|
-
.Where(p => !p.IsDeleted)
|
|
211
|
-
.Select(p => new ProductSummaryDto
|
|
212
|
-
{
|
|
213
|
-
Id = p.Id,
|
|
214
|
-
Name = p.Name,
|
|
215
|
-
Price = p.Price,
|
|
216
|
-
CategoryName = p.Category.Name,
|
|
217
|
-
OrderCount = p.OrderItems.Count
|
|
218
|
-
})
|
|
219
|
-
.ToListAsync(ct);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Compiled Queries
|
|
225
|
-
|
|
226
|
-
```csharp
|
|
227
|
-
// Define compiled query as static field
|
|
228
|
-
private static readonly Func<AppDbContext, int, CancellationToken, Task<Product?>>
|
|
229
|
-
GetProductByIdCompiled = EF.CompileAsyncQuery(
|
|
230
|
-
(AppDbContext context, int id, CancellationToken ct) =>
|
|
231
|
-
context.Products
|
|
232
|
-
.Include(p => p.Category)
|
|
233
|
-
.FirstOrDefault(p => p.Id == id));
|
|
234
|
-
|
|
235
|
-
public async Task<Product?> GetProductByIdOptimized(int id, CancellationToken ct = default)
|
|
236
|
-
{
|
|
237
|
-
return await GetProductByIdCompiled(context, id, ct);
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## Bulk Operations
|
|
242
|
-
|
|
243
|
-
```csharp
|
|
244
|
-
public class BulkProductRepository(AppDbContext context)
|
|
245
|
-
{
|
|
246
|
-
// Bulk insert
|
|
247
|
-
public async Task AddRangeAsync(List<Product> products, CancellationToken ct = default)
|
|
248
|
-
{
|
|
249
|
-
await context.Products.AddRangeAsync(products, ct);
|
|
250
|
-
await context.SaveChangesAsync(ct);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Bulk update with ExecuteUpdate (.NET 7+)
|
|
254
|
-
public async Task IncreasePricesAsync(decimal percentage, CancellationToken ct = default)
|
|
255
|
-
{
|
|
256
|
-
await context.Products
|
|
257
|
-
.Where(p => !p.IsDeleted)
|
|
258
|
-
.ExecuteUpdateAsync(
|
|
259
|
-
setters => setters.SetProperty(p => p.Price, p => p.Price * (1 + percentage)),
|
|
260
|
-
ct);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Bulk delete with ExecuteDelete (.NET 7+)
|
|
264
|
-
public async Task DeleteDiscontinuedAsync(CancellationToken ct = default)
|
|
265
|
-
{
|
|
266
|
-
await context.Products
|
|
267
|
-
.Where(p => p.IsDeleted)
|
|
268
|
-
.ExecuteDeleteAsync(ct);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
## Transactions
|
|
274
|
-
|
|
275
|
-
```csharp
|
|
276
|
-
public class OrderService(AppDbContext context)
|
|
277
|
-
{
|
|
278
|
-
public async Task<Order> CreateOrderAsync(CreateOrderDto dto, CancellationToken ct = default)
|
|
279
|
-
{
|
|
280
|
-
using var transaction = await context.Database.BeginTransactionAsync(ct);
|
|
281
|
-
|
|
282
|
-
try
|
|
283
|
-
{
|
|
284
|
-
var order = new Order
|
|
285
|
-
{
|
|
286
|
-
OrderNumber = GenerateOrderNumber(),
|
|
287
|
-
CreatedAt = DateTime.UtcNow
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
await context.Orders.AddAsync(order, ct);
|
|
291
|
-
await context.SaveChangesAsync(ct);
|
|
292
|
-
|
|
293
|
-
// Update inventory
|
|
294
|
-
foreach (var item in dto.Items)
|
|
295
|
-
{
|
|
296
|
-
var product = await context.Products.FindAsync([item.ProductId], ct);
|
|
297
|
-
if (product is null)
|
|
298
|
-
throw new InvalidOperationException($"Product {item.ProductId} not found");
|
|
299
|
-
|
|
300
|
-
product.Stock -= item.Quantity;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
await context.SaveChangesAsync(ct);
|
|
304
|
-
await transaction.CommitAsync(ct);
|
|
305
|
-
|
|
306
|
-
return order;
|
|
307
|
-
}
|
|
308
|
-
catch
|
|
309
|
-
{
|
|
310
|
-
await transaction.RollbackAsync(ct);
|
|
311
|
-
throw;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
## Migrations
|
|
318
|
-
|
|
319
|
-
```bash
|
|
320
|
-
# Add migration
|
|
321
|
-
dotnet ef migrations add InitialCreate
|
|
322
|
-
|
|
323
|
-
# Update database
|
|
324
|
-
dotnet ef database update
|
|
325
|
-
|
|
326
|
-
# Generate SQL script
|
|
327
|
-
dotnet ef migrations script
|
|
328
|
-
|
|
329
|
-
# Remove last migration (if not applied)
|
|
330
|
-
dotnet ef migrations remove
|
|
331
|
-
|
|
332
|
-
# Revert to specific migration
|
|
333
|
-
dotnet ef database update PreviousMigrationName
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
```csharp
|
|
337
|
-
// Apply migrations programmatically
|
|
338
|
-
public static async Task ApplyMigrationsAsync(IServiceProvider services)
|
|
339
|
-
{
|
|
340
|
-
using var scope = services.CreateScope();
|
|
341
|
-
var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
342
|
-
await context.Database.MigrateAsync();
|
|
343
|
-
}
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
## Change Tracking Optimization
|
|
347
|
-
|
|
348
|
-
```csharp
|
|
349
|
-
// Disable change tracking for read-only operations
|
|
350
|
-
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
|
351
|
-
|
|
352
|
-
// Attach entity for updates without loading
|
|
353
|
-
public async Task UpdateProductPriceAsync(int id, decimal newPrice, CancellationToken ct = default)
|
|
354
|
-
{
|
|
355
|
-
var product = new Product { Id = id };
|
|
356
|
-
context.Products.Attach(product);
|
|
357
|
-
product.Price = newPrice;
|
|
358
|
-
context.Entry(product).Property(p => p.Price).IsModified = true;
|
|
359
|
-
await context.SaveChangesAsync(ct);
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## Interceptors (.NET 6+)
|
|
364
|
-
|
|
365
|
-
```csharp
|
|
366
|
-
public class AuditInterceptor : SaveChangesInterceptor
|
|
367
|
-
{
|
|
368
|
-
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
|
|
369
|
-
DbContextEventData eventData,
|
|
370
|
-
InterceptionResult<int> result,
|
|
371
|
-
CancellationToken ct = default)
|
|
372
|
-
{
|
|
373
|
-
if (eventData.Context is null)
|
|
374
|
-
return base.SavingChangesAsync(eventData, result, ct);
|
|
375
|
-
|
|
376
|
-
var entries = eventData.Context.ChangeTracker.Entries<BaseEntity>();
|
|
377
|
-
|
|
378
|
-
foreach (var entry in entries)
|
|
379
|
-
{
|
|
380
|
-
if (entry.State == EntityState.Added)
|
|
381
|
-
entry.Entity.CreatedAt = DateTime.UtcNow;
|
|
382
|
-
else if (entry.State == EntityState.Modified)
|
|
383
|
-
entry.Entity.UpdatedAt = DateTime.UtcNow;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
return base.SavingChangesAsync(eventData, result, ct);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Register interceptor
|
|
391
|
-
builder.Services.AddDbContext<AppDbContext>((sp, options) =>
|
|
392
|
-
{
|
|
393
|
-
options.UseSqlServer(connectionString)
|
|
394
|
-
.AddInterceptors(new AuditInterceptor());
|
|
395
|
-
});
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
## Quick Reference
|
|
399
|
-
|
|
400
|
-
| Operation | Method | Notes |
|
|
401
|
-
|-----------|--------|-------|
|
|
402
|
-
| Read-only query | `.AsNoTracking()` | Better performance |
|
|
403
|
-
| Eager loading | `.Include()` | Load related data |
|
|
404
|
-
| Filtered include | `.Include(x => x.Items.Where(...))` | .NET 5+ |
|
|
405
|
-
| Split query | `.AsSplitQuery()` | Avoid cartesian explosion |
|
|
406
|
-
| Bulk update | `.ExecuteUpdateAsync()` | .NET 7+ |
|
|
407
|
-
| Bulk delete | `.ExecuteDeleteAsync()` | .NET 7+ |
|
|
408
|
-
| Compiled query | `EF.CompileAsyncQuery()` | Reusable queries |
|
|
409
|
-
| Soft delete | Query filter | `HasQueryFilter()` |
|
|
1
|
+
# Entity Framework Core Patterns
|
|
2
|
+
|
|
3
|
+
## DbContext Setup
|
|
4
|
+
|
|
5
|
+
```csharp
|
|
6
|
+
using Microsoft.EntityFrameworkCore;
|
|
7
|
+
|
|
8
|
+
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
|
|
9
|
+
{
|
|
10
|
+
public DbSet<Product> Products => Set<Product>();
|
|
11
|
+
public DbSet<Category> Categories => Set<Category>();
|
|
12
|
+
public DbSet<Order> Orders => Set<Order>();
|
|
13
|
+
|
|
14
|
+
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
15
|
+
{
|
|
16
|
+
base.OnModelCreating(modelBuilder);
|
|
17
|
+
|
|
18
|
+
// Apply all configurations from assembly
|
|
19
|
+
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
|
|
20
|
+
|
|
21
|
+
// Global query filters
|
|
22
|
+
modelBuilder.Entity<Product>()
|
|
23
|
+
.HasQueryFilter(p => !p.IsDeleted);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Configuration class (recommended)
|
|
28
|
+
public class ProductConfiguration : IEntityTypeConfiguration<Product>
|
|
29
|
+
{
|
|
30
|
+
public void Configure(EntityTypeBuilder<Product> builder)
|
|
31
|
+
{
|
|
32
|
+
builder.ToTable("Products");
|
|
33
|
+
|
|
34
|
+
builder.HasKey(p => p.Id);
|
|
35
|
+
|
|
36
|
+
builder.Property(p => p.Name)
|
|
37
|
+
.IsRequired()
|
|
38
|
+
.HasMaxLength(200);
|
|
39
|
+
|
|
40
|
+
builder.Property(p => p.Price)
|
|
41
|
+
.HasPrecision(18, 2);
|
|
42
|
+
|
|
43
|
+
builder.HasIndex(p => p.Sku)
|
|
44
|
+
.IsUnique();
|
|
45
|
+
|
|
46
|
+
// Relationships
|
|
47
|
+
builder.HasOne(p => p.Category)
|
|
48
|
+
.WithMany(c => c.Products)
|
|
49
|
+
.HasForeignKey(p => p.CategoryId)
|
|
50
|
+
.OnDelete(DeleteBehavior.Restrict);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Entity Models
|
|
56
|
+
|
|
57
|
+
```csharp
|
|
58
|
+
// Base entity
|
|
59
|
+
public abstract class BaseEntity
|
|
60
|
+
{
|
|
61
|
+
public int Id { get; set; }
|
|
62
|
+
public DateTime CreatedAt { get; set; }
|
|
63
|
+
public DateTime? UpdatedAt { get; set; }
|
|
64
|
+
public bool IsDeleted { get; set; }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Product entity
|
|
68
|
+
public class Product : BaseEntity
|
|
69
|
+
{
|
|
70
|
+
public required string Name { get; set; }
|
|
71
|
+
public required string Sku { get; set; }
|
|
72
|
+
public decimal Price { get; set; }
|
|
73
|
+
public string? Description { get; set; }
|
|
74
|
+
|
|
75
|
+
// Navigation properties
|
|
76
|
+
public int CategoryId { get; set; }
|
|
77
|
+
public Category Category { get; set; } = null!;
|
|
78
|
+
|
|
79
|
+
public ICollection<OrderItem> OrderItems { get; set; } = [];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Value objects (owned types)
|
|
83
|
+
public class Address
|
|
84
|
+
{
|
|
85
|
+
public required string Street { get; init; }
|
|
86
|
+
public required string City { get; init; }
|
|
87
|
+
public required string Country { get; init; }
|
|
88
|
+
public required string PostalCode { get; init; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public class Order : BaseEntity
|
|
92
|
+
{
|
|
93
|
+
public required string OrderNumber { get; set; }
|
|
94
|
+
public Address ShippingAddress { get; set; } = null!;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Configuration for owned type
|
|
98
|
+
builder.OwnsOne(o => o.ShippingAddress, address =>
|
|
99
|
+
{
|
|
100
|
+
address.Property(a => a.Street).HasMaxLength(200);
|
|
101
|
+
address.Property(a => a.City).HasMaxLength(100);
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Repository Pattern
|
|
106
|
+
|
|
107
|
+
```csharp
|
|
108
|
+
public interface IRepository<T> where T : BaseEntity
|
|
109
|
+
{
|
|
110
|
+
Task<T?> GetByIdAsync(int id, CancellationToken ct = default);
|
|
111
|
+
Task<List<T>> GetAllAsync(CancellationToken ct = default);
|
|
112
|
+
Task<T> AddAsync(T entity, CancellationToken ct = default);
|
|
113
|
+
Task UpdateAsync(T entity, CancellationToken ct = default);
|
|
114
|
+
Task DeleteAsync(int id, CancellationToken ct = default);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public class Repository<T>(AppDbContext context) : IRepository<T> where T : BaseEntity
|
|
118
|
+
{
|
|
119
|
+
private readonly DbSet<T> _dbSet = context.Set<T>();
|
|
120
|
+
|
|
121
|
+
public async Task<T?> GetByIdAsync(int id, CancellationToken ct = default)
|
|
122
|
+
{
|
|
123
|
+
return await _dbSet.FindAsync([id], cancellationToken: ct);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public async Task<List<T>> GetAllAsync(CancellationToken ct = default)
|
|
127
|
+
{
|
|
128
|
+
return await _dbSet.AsNoTracking().ToListAsync(ct);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public async Task<T> AddAsync(T entity, CancellationToken ct = default)
|
|
132
|
+
{
|
|
133
|
+
entity.CreatedAt = DateTime.UtcNow;
|
|
134
|
+
await _dbSet.AddAsync(entity, ct);
|
|
135
|
+
await context.SaveChangesAsync(ct);
|
|
136
|
+
return entity;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public async Task UpdateAsync(T entity, CancellationToken ct = default)
|
|
140
|
+
{
|
|
141
|
+
entity.UpdatedAt = DateTime.UtcNow;
|
|
142
|
+
_dbSet.Update(entity);
|
|
143
|
+
await context.SaveChangesAsync(ct);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public async Task DeleteAsync(int id, CancellationToken ct = default)
|
|
147
|
+
{
|
|
148
|
+
var entity = await GetByIdAsync(id, ct);
|
|
149
|
+
if (entity is not null)
|
|
150
|
+
{
|
|
151
|
+
entity.IsDeleted = true;
|
|
152
|
+
await UpdateAsync(entity, ct);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Query Optimization
|
|
159
|
+
|
|
160
|
+
```csharp
|
|
161
|
+
public class ProductRepository(AppDbContext context)
|
|
162
|
+
{
|
|
163
|
+
// AsNoTracking for read-only queries
|
|
164
|
+
public async Task<List<ProductDto>> GetProductsAsync(CancellationToken ct = default)
|
|
165
|
+
{
|
|
166
|
+
return await context.Products
|
|
167
|
+
.AsNoTracking()
|
|
168
|
+
.Select(p => new ProductDto
|
|
169
|
+
{
|
|
170
|
+
Id = p.Id,
|
|
171
|
+
Name = p.Name,
|
|
172
|
+
Price = p.Price
|
|
173
|
+
})
|
|
174
|
+
.ToListAsync(ct);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Include related data (eager loading)
|
|
178
|
+
public async Task<Product?> GetProductWithCategoryAsync(int id, CancellationToken ct = default)
|
|
179
|
+
{
|
|
180
|
+
return await context.Products
|
|
181
|
+
.Include(p => p.Category)
|
|
182
|
+
.FirstOrDefaultAsync(p => p.Id == id, ct);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Split queries for collections
|
|
186
|
+
public async Task<Order?> GetOrderWithItemsAsync(int id, CancellationToken ct = default)
|
|
187
|
+
{
|
|
188
|
+
return await context.Orders
|
|
189
|
+
.Include(o => o.OrderItems)
|
|
190
|
+
.ThenInclude(oi => oi.Product)
|
|
191
|
+
.AsSplitQuery() // Prevents cartesian explosion
|
|
192
|
+
.FirstOrDefaultAsync(o => o.Id == id, ct);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Filtered includes (.NET 5+)
|
|
196
|
+
public async Task<Category?> GetCategoryWithActiveProducts(
|
|
197
|
+
int id,
|
|
198
|
+
CancellationToken ct = default)
|
|
199
|
+
{
|
|
200
|
+
return await context.Categories
|
|
201
|
+
.Include(c => c.Products.Where(p => p.Price > 0))
|
|
202
|
+
.FirstOrDefaultAsync(c => c.Id == id, ct);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Projection for performance
|
|
206
|
+
public async Task<List<ProductSummaryDto>> GetProductSummariesAsync(
|
|
207
|
+
CancellationToken ct = default)
|
|
208
|
+
{
|
|
209
|
+
return await context.Products
|
|
210
|
+
.Where(p => !p.IsDeleted)
|
|
211
|
+
.Select(p => new ProductSummaryDto
|
|
212
|
+
{
|
|
213
|
+
Id = p.Id,
|
|
214
|
+
Name = p.Name,
|
|
215
|
+
Price = p.Price,
|
|
216
|
+
CategoryName = p.Category.Name,
|
|
217
|
+
OrderCount = p.OrderItems.Count
|
|
218
|
+
})
|
|
219
|
+
.ToListAsync(ct);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Compiled Queries
|
|
225
|
+
|
|
226
|
+
```csharp
|
|
227
|
+
// Define compiled query as static field
|
|
228
|
+
private static readonly Func<AppDbContext, int, CancellationToken, Task<Product?>>
|
|
229
|
+
GetProductByIdCompiled = EF.CompileAsyncQuery(
|
|
230
|
+
(AppDbContext context, int id, CancellationToken ct) =>
|
|
231
|
+
context.Products
|
|
232
|
+
.Include(p => p.Category)
|
|
233
|
+
.FirstOrDefault(p => p.Id == id));
|
|
234
|
+
|
|
235
|
+
public async Task<Product?> GetProductByIdOptimized(int id, CancellationToken ct = default)
|
|
236
|
+
{
|
|
237
|
+
return await GetProductByIdCompiled(context, id, ct);
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Bulk Operations
|
|
242
|
+
|
|
243
|
+
```csharp
|
|
244
|
+
public class BulkProductRepository(AppDbContext context)
|
|
245
|
+
{
|
|
246
|
+
// Bulk insert
|
|
247
|
+
public async Task AddRangeAsync(List<Product> products, CancellationToken ct = default)
|
|
248
|
+
{
|
|
249
|
+
await context.Products.AddRangeAsync(products, ct);
|
|
250
|
+
await context.SaveChangesAsync(ct);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Bulk update with ExecuteUpdate (.NET 7+)
|
|
254
|
+
public async Task IncreasePricesAsync(decimal percentage, CancellationToken ct = default)
|
|
255
|
+
{
|
|
256
|
+
await context.Products
|
|
257
|
+
.Where(p => !p.IsDeleted)
|
|
258
|
+
.ExecuteUpdateAsync(
|
|
259
|
+
setters => setters.SetProperty(p => p.Price, p => p.Price * (1 + percentage)),
|
|
260
|
+
ct);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Bulk delete with ExecuteDelete (.NET 7+)
|
|
264
|
+
public async Task DeleteDiscontinuedAsync(CancellationToken ct = default)
|
|
265
|
+
{
|
|
266
|
+
await context.Products
|
|
267
|
+
.Where(p => p.IsDeleted)
|
|
268
|
+
.ExecuteDeleteAsync(ct);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Transactions
|
|
274
|
+
|
|
275
|
+
```csharp
|
|
276
|
+
public class OrderService(AppDbContext context)
|
|
277
|
+
{
|
|
278
|
+
public async Task<Order> CreateOrderAsync(CreateOrderDto dto, CancellationToken ct = default)
|
|
279
|
+
{
|
|
280
|
+
using var transaction = await context.Database.BeginTransactionAsync(ct);
|
|
281
|
+
|
|
282
|
+
try
|
|
283
|
+
{
|
|
284
|
+
var order = new Order
|
|
285
|
+
{
|
|
286
|
+
OrderNumber = GenerateOrderNumber(),
|
|
287
|
+
CreatedAt = DateTime.UtcNow
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
await context.Orders.AddAsync(order, ct);
|
|
291
|
+
await context.SaveChangesAsync(ct);
|
|
292
|
+
|
|
293
|
+
// Update inventory
|
|
294
|
+
foreach (var item in dto.Items)
|
|
295
|
+
{
|
|
296
|
+
var product = await context.Products.FindAsync([item.ProductId], ct);
|
|
297
|
+
if (product is null)
|
|
298
|
+
throw new InvalidOperationException($"Product {item.ProductId} not found");
|
|
299
|
+
|
|
300
|
+
product.Stock -= item.Quantity;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
await context.SaveChangesAsync(ct);
|
|
304
|
+
await transaction.CommitAsync(ct);
|
|
305
|
+
|
|
306
|
+
return order;
|
|
307
|
+
}
|
|
308
|
+
catch
|
|
309
|
+
{
|
|
310
|
+
await transaction.RollbackAsync(ct);
|
|
311
|
+
throw;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Migrations
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Add migration
|
|
321
|
+
dotnet ef migrations add InitialCreate
|
|
322
|
+
|
|
323
|
+
# Update database
|
|
324
|
+
dotnet ef database update
|
|
325
|
+
|
|
326
|
+
# Generate SQL script
|
|
327
|
+
dotnet ef migrations script
|
|
328
|
+
|
|
329
|
+
# Remove last migration (if not applied)
|
|
330
|
+
dotnet ef migrations remove
|
|
331
|
+
|
|
332
|
+
# Revert to specific migration
|
|
333
|
+
dotnet ef database update PreviousMigrationName
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
```csharp
|
|
337
|
+
// Apply migrations programmatically
|
|
338
|
+
public static async Task ApplyMigrationsAsync(IServiceProvider services)
|
|
339
|
+
{
|
|
340
|
+
using var scope = services.CreateScope();
|
|
341
|
+
var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
342
|
+
await context.Database.MigrateAsync();
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Change Tracking Optimization
|
|
347
|
+
|
|
348
|
+
```csharp
|
|
349
|
+
// Disable change tracking for read-only operations
|
|
350
|
+
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
|
351
|
+
|
|
352
|
+
// Attach entity for updates without loading
|
|
353
|
+
public async Task UpdateProductPriceAsync(int id, decimal newPrice, CancellationToken ct = default)
|
|
354
|
+
{
|
|
355
|
+
var product = new Product { Id = id };
|
|
356
|
+
context.Products.Attach(product);
|
|
357
|
+
product.Price = newPrice;
|
|
358
|
+
context.Entry(product).Property(p => p.Price).IsModified = true;
|
|
359
|
+
await context.SaveChangesAsync(ct);
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Interceptors (.NET 6+)
|
|
364
|
+
|
|
365
|
+
```csharp
|
|
366
|
+
public class AuditInterceptor : SaveChangesInterceptor
|
|
367
|
+
{
|
|
368
|
+
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
|
|
369
|
+
DbContextEventData eventData,
|
|
370
|
+
InterceptionResult<int> result,
|
|
371
|
+
CancellationToken ct = default)
|
|
372
|
+
{
|
|
373
|
+
if (eventData.Context is null)
|
|
374
|
+
return base.SavingChangesAsync(eventData, result, ct);
|
|
375
|
+
|
|
376
|
+
var entries = eventData.Context.ChangeTracker.Entries<BaseEntity>();
|
|
377
|
+
|
|
378
|
+
foreach (var entry in entries)
|
|
379
|
+
{
|
|
380
|
+
if (entry.State == EntityState.Added)
|
|
381
|
+
entry.Entity.CreatedAt = DateTime.UtcNow;
|
|
382
|
+
else if (entry.State == EntityState.Modified)
|
|
383
|
+
entry.Entity.UpdatedAt = DateTime.UtcNow;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return base.SavingChangesAsync(eventData, result, ct);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Register interceptor
|
|
391
|
+
builder.Services.AddDbContext<AppDbContext>((sp, options) =>
|
|
392
|
+
{
|
|
393
|
+
options.UseSqlServer(connectionString)
|
|
394
|
+
.AddInterceptors(new AuditInterceptor());
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Quick Reference
|
|
399
|
+
|
|
400
|
+
| Operation | Method | Notes |
|
|
401
|
+
|-----------|--------|-------|
|
|
402
|
+
| Read-only query | `.AsNoTracking()` | Better performance |
|
|
403
|
+
| Eager loading | `.Include()` | Load related data |
|
|
404
|
+
| Filtered include | `.Include(x => x.Items.Where(...))` | .NET 5+ |
|
|
405
|
+
| Split query | `.AsSplitQuery()` | Avoid cartesian explosion |
|
|
406
|
+
| Bulk update | `.ExecuteUpdateAsync()` | .NET 7+ |
|
|
407
|
+
| Bulk delete | `.ExecuteDeleteAsync()` | .NET 7+ |
|
|
408
|
+
| Compiled query | `EF.CompileAsyncQuery()` | Reusable queries |
|
|
409
|
+
| Soft delete | Query filter | `HasQueryFilter()` |
|