Skip to content

Fix SQLite ExecuteUpdate with navigation properties#38056

Merged
roji merged 3 commits intomainfrom
roji/fix-sqlite-update-alias
Apr 8, 2026
Merged

Fix SQLite ExecuteUpdate with navigation properties#38056
roji merged 3 commits intomainfrom
roji/fix-sqlite-update-alias

Conversation

@roji
Copy link
Copy Markdown
Member

@roji roji commented Apr 6, 2026

Fixes #38010
Fixes #31402

Problem

SQLite doesn't support referencing the UPDATE target table alias in JOIN ON clauses. When ExecuteUpdate uses navigation properties in the Where clause (or with TPT inheritance), EF Core generates SQL with JOINs that requires an alias on the UPDATE target table. This causes SqliteException: no such column errors.

Solution

Override VisitUpdate in SqliteQuerySqlGenerator with two strategies:

Single-table updates (base path + VisitTable/VisitColumn overrides):

  • Emit UPDATE "TableName" without alias
  • Replace alias references with the table name in column expressions

Multi-table updates (custom FROM rendering):

  • Emit UPDATE "TableName" without alias
  • Selectively lift join predicates that reference the update target into the WHERE clause (since the alias isn't available in the FROM context)
  • Preserve other joins (e.g. LEFT JOIN between non-target tables) intact

Example

Before (invalid SQLite):

UPDATE "CompanyItems" AS "c"
SET "BoolProp" = @p
FROM "Items" AS "i"
INNER JOIN "Companies" AS "c0" ON "c"."CompanyId" = "c0"."Id"
WHERE "c"."ItemId" = "i"."Id"

After (valid SQLite):

UPDATE "CompanyItems"
SET "BoolProp" = @p
FROM "Items" AS "i",
"Companies" AS "c0"
WHERE "CompanyItems"."CompanyId" = "c0"."Id" AND "CompanyItems"."ItemId" = "i"."Id"

Copilot AI review requested due to automatic review settings April 6, 2026 19:08
@roji roji requested a review from a team as a code owner April 6, 2026 19:08
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates EF Core’s SQLite SQL generation for ExecuteUpdate to avoid emitting UPDATE ... AS alias, which SQLite doesn’t support, fixing failures when updates involve navigation predicates or TPT inheritance joins.

Changes:

  • Override SqliteQuerySqlGenerator.VisitUpdate to generate alias-free UPDATE statements and rewrite multi-table updates by lifting target-referencing join predicates into WHERE.
  • Adjust SQL baselines across SQLite bulk update functional tests to reflect the new alias-free SQL output.
  • Re-enable previously failing TPT ExecuteUpdate scenarios by asserting the new valid SQL rather than expecting SqliteException.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs Adds SQLite-specific UPDATE SQL generation to avoid target-table aliases and to rewrite joins/predicates for SQLite scoping rules.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs Updates expected SQL baselines for many ExecuteUpdate scenarios to use non-aliased UPDATE targets and qualified table-name column references.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs Updates expected SQL baselines for non-shared model bulk updates to match alias-free UPDATE target rendering.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/Inheritance/TPTInheritanceBulkUpdatesSqliteTest.cs Converts previously failing TPT ExecuteUpdate tests from expecting exceptions to asserting the new valid SQL.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/Inheritance/TPTFiltersInheritanceBulkUpdatesSqliteTest.cs Same as above, but for filtered TPT scenarios; updates expected SQL accordingly.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/Inheritance/TPHInheritanceBulkUpdatesSqliteTest.cs Updates TPH expected SQL baselines to remove UPDATE target aliases and qualify column references with the table name.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/Inheritance/TPHFiltersInheritanceBulkUpdatesSqliteTest.cs Updates filtered TPH expected SQL baselines to the new alias-free UPDATE output.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/Inheritance/TPCInheritanceBulkUpdatesSqliteTest.cs Updates TPC expected SQL baselines to remove UPDATE target aliases.
test/EFCore.Sqlite.FunctionalTests/BulkUpdates/Inheritance/TPCFiltersInheritanceBulkUpdatesSqliteTest.cs Updates filtered TPC expected SQL baselines to the new alias-free UPDATE output.

Comment thread src/EFCore.Sqlite.Core/Query/Internal/SqliteQuerySqlGenerator.cs Outdated
@roji roji force-pushed the roji/fix-sqlite-update-alias branch from b4dbd39 to a2d7390 Compare April 6, 2026 21:52
Copilot AI review requested due to automatic review settings April 6, 2026 21:56
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread src/EFCore.Sqlite.Core/Query/Internal/SqliteUpdateJoinLiftingVisitor.cs Outdated
Comment thread src/EFCore.Sqlite.Core/Query/Internal/SqliteUpdateJoinLiftingVisitor.cs Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Fixes #38010
Fixes #31402

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@roji roji force-pushed the roji/fix-sqlite-update-alias branch from 875d5a8 to e038a97 Compare April 7, 2026 10:13
@roji roji enabled auto-merge (squash) April 7, 2026 10:21
Copilot AI review requested due to automatic review settings April 7, 2026 15:28
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

@roji roji merged commit c037bc1 into main Apr 8, 2026
15 checks passed
@roji roji deleted the roji/fix-sqlite-update-alias branch April 8, 2026 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants