The command you need:
dotnet ef migrations add MyMigration -- /p:RunAnalyzersDuringBuild=false
dotnet ef database update -- /p:RunAnalyzersDuringBuild=false
The -- separator tells the EF CLI to pass RunAnalyzersDuringBuild=false directly to MSBuild. This disables Roslyn analyzer execution during the EF tool’s internal project build — and only during that build. Your main application build’s security analysis is unaffected.
Why dotnet ef Triggers Roslyn Analyzers
When you run dotnet ef migrations add or dotnet ef database update, the EF Core CLI builds your project internally to discover your DbContext, entity types, and migration history. This internal build runs the full MSBuild pipeline — including every Roslyn analyzer configured in your project.
If your .csproj includes:
<TreatWarningsAsErrors>true</TreatWarningsAsErrors><WarningsAsErrors>CA2100;CA3001;...</WarningsAsErrors>/warnaserrorin your build arguments- A SAST analyzer NuGet package (
SecurityCodeScan.VS2019,SonarAnalyzer.CSharp, or similar)
…then an analyzer warning during the EF internal build becomes a build error, and the migration command aborts before it does anything useful.
The EF CLI doesn’t care about your security analysis results — it just needs to compile the project to find your DbContext. RunAnalyzersDuringBuild=false skips the analysis step so EF can do its job.
All Command Variants
Both /p: (Windows-style MSBuild property prefix) and -p: (Unix-style) work identically on all platforms.
dotnet ef migrations add
# Windows-style (works on Windows, Linux, macOS)
dotnet ef migrations add MyMigration -- /p:RunAnalyzersDuringBuild=false
# Unix-style short form (works on Windows, Linux, macOS)
dotnet ef migrations add MyMigration -- -p:RunAnalyzersDuringBuild=false
# With explicit project and startup project
dotnet ef migrations add MyMigration \
--project src/DataAccess \
--startup-project src/Api \
-- /p:RunAnalyzersDuringBuild=false
# PowerShell — quote if the shell strips the slash
dotnet ef migrations add MyMigration -- "/p:RunAnalyzersDuringBuild=false"
# Also disable code style enforcement if needed
dotnet ef migrations add MyMigration \
-- /p:RunAnalyzersDuringBuild=false /p:EnforceCodeStyleInBuild=false
dotnet ef database update
# Apply all pending migrations
dotnet ef database update -- /p:RunAnalyzersDuringBuild=false
# Target a specific migration by name
dotnet ef database update TargetMigrationName -- /p:RunAnalyzersDuringBuild=false
# With project paths and Unix-style flag
dotnet ef database update \
--project src/DataAccess \
--startup-project src/Api \
-- -p:RunAnalyzersDuringBuild=false
Other EF commands
# dotnet ef dbcontext scaffold
dotnet ef dbcontext scaffold "ConnectionString" Microsoft.EntityFrameworkCore.SqlServer \
-- /p:RunAnalyzersDuringBuild=false
# dotnet ef migrations script
dotnet ef migrations script -- /p:RunAnalyzersDuringBuild=false
Why the -- Is Required
Without the -- separator, dotnet ef attempts to parse /p:RunAnalyzersDuringBuild=false as its own command-line argument and fails with:
Unrecognized option '/p:RunAnalyzersDuringBuild=false'
The -- tells dotnet ef that everything after it should be passed directly to the underlying MSBuild invocation. This is a standard EF Core 5.0+ CLI feature.
If you see Error: unknown option '--', your dotnet-ef tool needs an update:
dotnet tool update --global dotnet-ef
Do Not Set RunAnalyzersDuringBuild=false Globally
The most common mistake when solving this problem:
<!-- ⚠️ DO NOT DO THIS — disables ALL Roslyn security analysis globally -->
<PropertyGroup>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
</PropertyGroup>
Setting this unconditionally in your .csproj silently disables security analysis on every build — including your CI security scan build. Rules like CA2100 (SQL injection), CA3001 (XSS), and CA5351 (broken cryptography) stop running with no visible error. Your build log shows success while security analysis has been completely disabled.
The right approach: Pass RunAnalyzersDuringBuild=false only to dotnet ef commands via the -- separator.
Conditional .csproj Configuration (Alternative Approach)
If you want to avoid typing the flag on every dotnet ef command, you can disable analyzers only during design-time builds in your .csproj:
<!-- Disable analyzers only when Visual Studio or dotnet ef triggers a design-time build -->
<PropertyGroup Condition="'$(DesignTimeBuild)' == 'true'">
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
</PropertyGroup>
This disables Roslyn analyzer execution when the EF CLI or Visual Studio tooling trigger a design-time build but leaves analyzers fully enabled for your regular dotnet build, CI builds, and security scans.
A more targeted alternative — only suppress for an explicit migration flag:
<PropertyGroup Condition="'$(SkipAnalyzersForEF)' == 'true'">
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
</PropertyGroup>
Then pass it via the -- separator:
dotnet ef migrations add MyMigration -- /p:SkipAnalyzersForEF=true
The Correct CI/CD Pattern
The goal is to disable analyzers only for the EF migration step, while keeping them enabled for your main application build:
GitHub Actions
name: Build, Analyze & Migrate
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build-and-analyze:
name: Build + Security Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- name: Restore
run: dotnet restore
# ✅ Analyzers run here — this IS your security gate
- name: Build with Roslyn security analyzers
run: |
dotnet build --configuration Release \
/p:RunAnalyzersDuringBuild=true \
/p:AnalysisLevel=latest-recommended \
/warnaserror:CA2100,CA3001,CA3006,CA5350,CA5351
migrate:
name: Apply EF Migrations
runs-on: ubuntu-latest
needs: build-and-analyze
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- name: Install EF CLI
run: dotnet tool install --global dotnet-ef
# ✅ Analyzers disabled ONLY for the EF migration build step
- name: Apply Migrations
run: |
dotnet ef database update \
--project src/DataAccess \
-- /p:RunAnalyzersDuringBuild=false
env:
ConnectionStrings__Default: ${{ secrets.PROD_DB_CONNECTION }}
Key principles:
- The
build-and-analyzejob runs with analyzers fully enabled — security gate intact - The
migratejob runs only after a successful analyzed build (needs: build-and-analyze) RunAnalyzersDuringBuild=falseappears only in thedotnet efcommand, not in the main build
Azure DevOps
# azure-pipelines.yml
trigger:
- main
stages:
- stage: Build
jobs:
- job: BuildAndAnalyze
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UseDotNet@2
inputs:
version: '8.x'
- script: dotnet restore
displayName: Restore
# ✅ Security-gated build
- script: |
dotnet build --configuration Release \
/p:RunAnalyzersDuringBuild=true \
/warnaserror:CA2100,CA3001,CA3006,CA5350,CA5351
displayName: Build + Security Analysis
- stage: Migrate
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- job: ApplyMigrations
pool:
vmImage: 'ubuntu-latest'
steps:
- script: dotnet tool install --global dotnet-ef
displayName: Install EF Tools
# ✅ Analyzers disabled only for EF migration
- script: |
dotnet ef database update \
--project src/DataAccess \
-- /p:RunAnalyzersDuringBuild=false
displayName: Apply EF Migrations
env:
ConnectionStrings__Default: $(ProdDbConnection)
Why Roslyn Security Analyzers Fire on EF Migration Code
The specific rules that most commonly cause dotnet ef to fail:
| Rule | What It Flags | Why EF Migration Code Triggers It |
|---|---|---|
CA2100 | SQL injection in SqlCommand | Helper methods in migration files using raw SQL |
CA3001–CA3012 | Various injection patterns | Scaffolded or generated code with raw queries |
CA5394 | Insecure System.Random usage | Seed data generation using Random |
CS8600–CS8629 | Nullable reference warnings | Older-style generated migration code |
IDE0xxx | Code style violations | Auto-generated migration classes don’t match style rules |
EF migration files are auto-generated — they should not be modified to satisfy style rules. Suppressing analyzers for the dotnet ef build step is the correct approach.
Should You Disable Analyzers for the EF Build?
Yes — it is safe to pass RunAnalyzersDuringBuild=false to dotnet ef commands because:
- EF migration files are generated code, not user-facing code that processes untrusted input — they run during deployment, not during request handling
- Your application’s security-relevant code (controllers, services, repositories) is analyzed in your main build step, not in the EF tool build
- The flag is surgical — it only affects the design-time build triggered by
dotnet ef, not your regulardotnet buildor CI security scans
However, Roslyn analyzers have an important limitation: they perform only intra-method analysis. They detect SQL injection when SqlCommand is built with string concatenation in the same method as a Request.QueryString read — but they miss complex injection chains that span multiple methods, service layers, or class boundaries.
For that level of coverage — including second-order SQL injection, stored XSS, and interprocedural data flow analysis — a dedicated SAST platform with full taint analysis is required alongside Roslyn analyzers.
Troubleshooting
Error: unknown option '--'
Your dotnet-ef global tool is outdated. Update it:
dotnet tool update --global dotnet-ef
# Verify version (must be 5.0+)
dotnet ef --version
Command fails after adding the flag
If the EF command still fails, check for EnforceCodeStyleInBuild:
# Disable both analyzer types
dotnet ef migrations add MyMigration \
-- /p:RunAnalyzersDuringBuild=false /p:EnforceCodeStyleInBuild=false
Analyzers still running in CI after adding the flag
Verify the -- is correctly formatted with spaces on both sides:
# Correct — space before and after --
dotnet ef database update -- /p:RunAnalyzersDuringBuild=false
# Wrong — flag interpreted by dotnet ef, not MSBuild
dotnet ef database update/p:RunAnalyzersDuringBuild=false
dotnet ef fails in Docker
# Install EF CLI in the build layer
RUN dotnet tool install --global dotnet-ef
ENV PATH="$PATH:/root/.dotnet/tools"
# Apply migrations with analyzers disabled
RUN dotnet ef database update -- /p:RunAnalyzersDuringBuild=false
Quick Reference
| Task | Command |
|---|---|
migrations add (Windows / Linux / macOS) | dotnet ef migrations add Name -- /p:RunAnalyzersDuringBuild=false |
migrations add (Unix-style flag) | dotnet ef migrations add Name -- -p:RunAnalyzersDuringBuild=false |
database update | dotnet ef database update -- /p:RunAnalyzersDuringBuild=false |
database update + code style disabled | dotnet ef database update -- /p:RunAnalyzersDuringBuild=false /p:EnforceCodeStyleInBuild=false |
| Main app build (keep analyzers ON) | dotnet build /p:RunAnalyzersDuringBuild=true |
| Security-gated CI build | dotnet build /warnaserror:CA2100,CA3001,CA3006 |
Frequently Asked Questions
Does -- /p:RunAnalyzersDuringBuild=false work on Linux and macOS?
Yes. Both /p: and -p: MSBuild property prefix styles work on all platforms in modern .NET. The -- separator is a standard EF Core CLI feature available from EF Core 5.0+ tooling.
Does this flag skip running migrations?
No. RunAnalyzersDuringBuild=false only skips Roslyn analyzer execution during the EF tool’s internal project build. Migration files are still generated or applied exactly as they would be without the flag.
Why does dotnet ef succeed locally but fail in CI?
CI pipelines typically enforce stricter build settings than local development:
- CI may set
/warnaserrorglobally, which your local build doesn’t have - CI may use a different .NET SDK version with more security rules enabled by default
- CI may have newer NuGet analyzer packages that fire on previously undetected patterns
Add -- /p:RunAnalyzersDuringBuild=false to your CI EF migration step to resolve all of these.
Is RunAnalyzersDuringBuild the same as RunCodeAnalysis?
No. RunAnalyzersDuringBuild controls whether Roslyn source analyzers (NuGet-based and SDK-built-in analyzers) run during the build. RunCodeAnalysis controls the older FxCop-style binary analysis. In modern .NET projects, RunAnalyzersDuringBuild=false is the relevant flag for the EF issue.
For the complete guide covering all scenarios, Docker configuration, and the full CI/CD pipeline pattern with SAST integration, see: dotnet ef RunAnalyzersDuringBuild=false — Complete Guide.
For deeper security coverage of your .NET codebase beyond what Roslyn analyzers provide — including interprocedural taint analysis and second-order injection detection — Offensive360 SAST runs as a separate step in your CI/CD pipeline, completely independent of RunAnalyzersDuringBuild. Run a one-time .NET SAST scan for $500 or book a demo.