Skip to content

Differentiate overloaded functions and stored procedures in TableMappingBaseComparer - #39211

Open
SkyDevLab wants to merge 2 commits into
dotnet:mainfrom
SkyDevLab:fix/33542-overloaded-dbfunction-relational-model
Open

SkyDevLab wants to merge 2 commits into
dotnet:mainfrom
SkyDevLab:fix/33542-overloaded-dbfunction-relational-model

Conversation

@SkyDevLab

@SkyDevLab SkyDevLab commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #33542

Description

When table-valued functions (TVFs) or stored procedures share the same name and schema but differ in parameter count or parameter types (overloads), TableMappingBaseComparer previously compared them only by Table.Name and Table.Schema. As a result, different store function mappings were treated as identical (Compare returned 0).

Because FunctionColumnMappings on IProperty uses SortedSet<FunctionColumnMapping> (which sorts via ColumnMappingBaseComparer and delegates to TableMappingBaseComparer), mappings for subsequent overloaded TVFs were dropped as duplicates. At query translation time, storeFunction.FindColumn(property) returned null for the omitted overload, causing NullReferenceException in ConcreteColumnExpression.

This PR updates TableMappingBaseComparer:

  • Compares IStoreFunction instances by parameter count, followed by parameter StoreType and Name.
  • Compares IStoreStoredProcedure instances by parameter count, followed by parameter StoreType and Name.
  • Updates GetHashCode to include function and stored procedure parameter attributes, keeping it consistent with Equals and Compare.

Testing

  • Updated Can_use_relational_model_with_functions in RelationalModelTest to assert that all 3 function column mappings are retained for overloaded functions.
  • Verified FindColumn returns the mapped column for both overloaded functions.
  • All RelationalModelTest tests pass.

…ingBaseComparer

When table-valued functions or stored procedures share the same name and schema but differ in parameter count or types, TableMappingBaseComparer previously compared them only by Table.Name and Table.Schema, causing them to compare as equal. When stored in a SortedSet (such as FunctionColumnMappings on IProperty), mappings for overloaded functions were dropped as duplicates, leading to NullReferenceException when translating queries.

Fixes dotnet#33542

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Only a minor test-coverage nit remains; no blocking issues were identified.

0 open findings

What changed in this PR

This PR fixes overloaded TVF and stored procedure mapping collisions by comparing parameter signatures.

Changes:

  • Compare parameter count, store type, and name.
  • Update hash computation consistently.
  • Expand regression coverage for overloaded functions.
File Summary
test/​EFCore.Relational.Tests/​Metadata/​RelationalModelTest.cs Verifies overloaded function mappings and column lookup.
src/​EFCore.Relational/​Metadata/​Internal/​TableMappingBaseComparer.cs Adds parameter-aware comparison and hashing. Nit: add coverage for overloads with different parameter counts.

🧠 Review effort: Lite


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

return result;
}

if (x.Table is IStoreFunction xFunction)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of casting here derive from IComparable in ITableMappingBase and IColumnMappingBase and implement them as appropriate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated in commit fdceb8e. Derived ITableMappingBase from IComparable and IColumnMappingBase from IComparable. Implemented CompareTo on ColumnMappingBase and TableMappingBase, and overridden in FunctionMapping and StoredProcedureMapping to compare parameter details. TableMappingBaseComparer and ColumnMappingBaseComparer now delegate cleanly to CompareTo without type casting.

@SkyDevLab
SkyDevLab force-pushed the fix/33542-overloaded-dbfunction-relational-model branch from fdceb8e to 4564281 Compare October 13, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overloaded HasDbFunction throws NullReferenceException in ConcreteColumnExpression constructor

3 participants