Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Application Security

dotnet ef database update: Skip Analyzers

dotnet ef failing on Roslyn analyzer errors? Pass -- /p:RunAnalyzersDuringBuild=false after the separator. All variants, CI/CD patterns and .csproj config.

Offensive360 Security Research Team — min read
dotnet ef RunAnalyzersDuringBuild dotnet ef migrations add dotnet ef database update RunAnalyzersDuringBuild=false Roslyn analyzers Entity Framework .NET static code analysis CI/CD security dotnet ef -- /p:RunAnalyzersDuringBuild=false dotnet ef migrations runanalyzersduringbuild

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>
  • /warnaserror in 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:

  1. The build-and-analyze job runs with analyzers fully enabled — security gate intact
  2. The migrate job runs only after a successful analyzed build (needs: build-and-analyze)
  3. RunAnalyzersDuringBuild=false appears only in the dotnet ef command, 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:

RuleWhat It FlagsWhy EF Migration Code Triggers It
CA2100SQL injection in SqlCommandHelper methods in migration files using raw SQL
CA3001–CA3012Various injection patternsScaffolded or generated code with raw queries
CA5394Insecure System.Random usageSeed data generation using Random
CS8600–CS8629Nullable reference warningsOlder-style generated migration code
IDE0xxxCode style violationsAuto-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:

  1. EF migration files are generated code, not user-facing code that processes untrusted input — they run during deployment, not during request handling
  2. Your application’s security-relevant code (controllers, services, repositories) is analyzed in your main build step, not in the EF tool build
  3. The flag is surgical — it only affects the design-time build triggered by dotnet ef, not your regular dotnet build or 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

TaskCommand
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 updatedotnet ef database update -- /p:RunAnalyzersDuringBuild=false
database update + code style disableddotnet ef database update -- /p:RunAnalyzersDuringBuild=false /p:EnforceCodeStyleInBuild=false
Main app build (keep analyzers ON)dotnet build /p:RunAnalyzersDuringBuild=true
Security-gated CI builddotnet 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 /warnaserror globally, 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.

Offensive360 Security Research Team

Application Security Research

Updated June 1, 2026

Find vulnerabilities before attackers do

Run Offensive360 SAST and DAST against your applications and get a full vulnerability report in minutes.