Skip to content

Fix EF Core 10 API breaking changes in query processor and modification command batch#109

Merged
renemadsen merged 3 commits intomasterfrom
copilot/fix-failing-tests-issue
Nov 16, 2025
Merged

Fix EF Core 10 API breaking changes in query processor and modification command batch#109
renemadsen merged 3 commits intomasterfrom
copilot/fix-failing-tests-issue

Conversation

Copy link

Copilot AI commented Nov 16, 2025

EF Core 10 introduced breaking changes in both the query processor API and the modification command batch system. This PR addresses both issues to ensure compatibility with EF Core 10.

Changes

Query Processor Migration

  • Replace obsolete Optimize() override with Process() in MySqlParameterBasedSqlProcessor
  • Add ProcessSqlNullability() override for explicit null handling delegation
  • Update SkipTakeCollapsingExpressionVisitor to accept ParametersCacheDecorator
    • Replace manual cache tracking (_canCache) with GetAndDisableCaching() call
  • Update MySqlParameterInliningExpressionVisitor similarly
    • Remove canCache out parameter from Process() signature

Modification Command Batch Fix

  • Remove custom _parameterValues dictionary from MySqlModificationCommandBatch
  • Use base class's ParameterValues property for storing parameter values
  • Simplify RollbackLastCommand to delegate to base implementation
  • Update AddParameterCore to use inherited ParameterValues property

Root Cause

EF Core 10 made two significant changes:

  1. Query Processor: Deprecated RelationalParameterBasedSqlProcessor.Optimize() in favor of Process() with ParametersCacheDecorator for better query caching control

  2. Modification Command Batch: Added a ParameterValues property to the base ReaderModificationCommandBatch class. The MySQL provider was maintaining its own _parameterValues dictionary, but EF Core 10 looks up parameter values from the base class's property, causing "No value was provided for the required parameter" errors during SaveChanges operations.

Migration Pattern

Before (EF Core 9):

public override Expression Optimize(
    Expression queryExpression,
    IReadOnlyDictionary<string, object?> parametersValues,
    out bool canCache)
{
    queryExpression = base.Optimize(queryExpression, parametersValues, out canCache);
    // Custom processing...
    canCache &= canCache2;
    return queryExpression;
}

After (EF Core 10):

public override Expression Process(
    Expression queryExpression, 
    ParametersCacheDecorator parametersDecorator)
{
    queryExpression = base.Process(queryExpression, parametersDecorator);
    // Custom processing with parametersDecorator.GetAndDisableCaching()
    return queryExpression;
}

Solution

Following the pattern used by SQL Server, PostgreSQL, and SQLite providers in EF Core 10, the MySQL provider now uses the inherited ParameterValues property from the base class instead of maintaining a separate dictionary.

Test Results

  • ✅ All 77 unit tests passing
  • ✅ All 4 TwoDatabasesMySqlTest functional tests passing (previously failing)
  • ✅ Build succeeds with no errors or warnings

Fixes #108

Original prompt

This section details on the original issue you should resolve

<issue_title>Fix failing tests</issue_title>
<issue_description>```
Error: Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while saving the entity changes. See the inner exception for details.
---- System.InvalidOperationException : No value was provided for the required parameter 'p1'.

Failed Pomelo.EntityFrameworkCore.MySql.FunctionalTests.TwoDatabasesMySqlTest.Can_set_connection_string_in_interceptor(withConnectionString: True, withNullConnectionString: True) [982 ms]
[xUnit.net 00:00:14.15] Pomelo.EntityFrameworkCore.MySql.FunctionalTests.TwoDatabasesMySqlTest.Can_set_connection_string_in_interceptor(withConnectionString: True, withNullConnectionString: False) [FAIL]
Error Message:
Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while saving the entity changes. See the inner exception for details.
---- System.InvalidOperationException : No value was provided for the required parameter 'p1'.
Stack Trace:
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable1 commandBatches, IRelationalConnection connection) at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList1 entriesToSave) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.<SaveChanges>b__114_0(DbContext _, ValueTuple2 t)
at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded) in /home/runner/work/Pomelo.EntityFrameworkCore.MySql/Pomelo.EntityFrameworkCore.MySql/src/EFCore.MySql/Storage/Internal/MySqlExecutionStrategy.cs:line 48
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at Microsoft.EntityFrameworkCore.TwoDatabasesTestBase.Can_set_connection_string_in_interceptor(Boolean withConnectionString, Boolean withNullConnectionString)
at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span1 copyOfArgs, BindingFlags invokeAttr) ----- Inner Stack Trace ----- at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalParameterBase.AddDbParameter(DbCommand command, IReadOnlyDictionary2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.CreateDbCommand(RelationalCommandParameterObject parameterObject, Guid commandId, DbCommandMethod commandMethod)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
[xUnit.net 00:00:14.15] Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while saving the entity changes. See the inner exception for details.
[xUnit.net 00:00:14.15] ---- System.InvalidOperationException : No value was provided for the required parameter 'p1'.
[xUnit.net 00:00:14.15] Stack Trace:
[xUnit.net 00:00:14.15] at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
[xUnit.net 00:00:14.15] at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable1 commandBatches, IRelationalConnection connection) [xUnit.net 00:00:14.15] at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList1 entries)
[xUnit.net 00:00:14.15] at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList1 entriesToSave) [xUnit.net 00:00:14.15] at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess) [xUnit.net 00:00:14.15] at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.<SaveChanges>b__114_0(DbContext _, ValueTuple2 t)
[xUnit.net 00:00:14.15] /home/runner/work/Pomelo.EntityFra...


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Replace obsolete Optimize method with Process method that uses ParametersCacheDecorator instead of IReadOnlyDictionary for parameter handling.

Co-authored-by: renemadsen <76994+renemadsen@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix failing tests in database connection handling Migrate query processor to EF Core 10 API - Replace obsolete Optimize with Process method Nov 16, 2025
Copilot AI requested a review from renemadsen November 16, 2025 17:43
@renemadsen
Copy link
Member

@copilot Do continue to investigate the issue for SaveChanges() and find a solution based on how SQL Server and PostgreSQL and SQLite solves it

In EF Core 10, ReaderModificationCommandBatch now provides a ParameterValues property. The MySQL provider was maintaining its own _parameterValues dictionary which caused parameter lookup failures during SaveChanges. Changed to use the base class's ParameterValues property instead, following the pattern used by SQL Server, PostgreSQL, and SQLite providers.

Co-authored-by: renemadsen <76994+renemadsen@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 16, 2025

@copilot Do continue to investigate the issue for SaveChanges() and find a solution based on how SQL Server and PostgreSQL and SQLite solves it

Fixed in commit 2c4520d.

The issue was that EF Core 10 added a ParameterValues property to the base ReaderModificationCommandBatch class. The MySQL provider was maintaining its own _parameterValues dictionary, but EF Core was looking up parameter values from the base class's property instead.

Changed to use the inherited ParameterValues property from the base class, following the same pattern as SQL Server, PostgreSQL, and SQLite providers. All tests now passing (77 unit tests + 4 TwoDatabasesMySqlTest functional tests).

Copilot AI changed the title Migrate query processor to EF Core 10 API - Replace obsolete Optimize with Process method Fix EF Core 10 API breaking changes in query processor and modification command batch Nov 16, 2025
@renemadsen renemadsen marked this pull request as ready for review November 16, 2025 18:04
@renemadsen renemadsen merged commit b87e6f3 into master Nov 16, 2025
0 of 54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix failing tests

2 participants