Description
Bug Description
When using a parameter name that matches (multiple) column names, RepoDB seems to derive the type of the parameter from a matching database column in the query, no matter the parameter definition provided.
In my reproduction example, I have 2 tables with a DeviceId property, one is a string, and one a int64 (foreign key).
When the query contains both columns (one to filter, one to join), the type mapping consistently chooses the wrong type for the parameter. As soon as the parameter name matches the column name, the type is wrongly defined no matter how I specify the parameter (I have also tried defining the parameter as described here in the documentation).
Exception Message:
System.FormatException: Failed to convert parameter value from a String to a Int64.
---> System.FormatException: Input string was not in a correct format.
at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
at System.String.System.IConvertible.ToInt64(IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Microsoft.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
--- End of inner exception stack trace ---
at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__209_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at RepoDb.DbConnectionExtension.ExecuteQueryAsyncInternalForType[TResult](IDbConnection connection, String commandText, Object param, Nullable`1 commandType, String cacheKey, Nullable`1 cacheItemExpiration, String traceKey, Nullable`1 commandTimeout, IDbTransaction transaction, ICache cache, ITrace trace, CancellationToken cancellationToken, String tableName, Boolean skipCommandArrayParametersCheck)
at RepoDb.DbConnectionExtension.ExecuteQueryAsyncInternal[TResult](IDbConnection connection, String commandText, Object param, Nullable`1 commandType, String cacheKey, Nullable`1 cacheItemExpiration, String traceKey, Nullable`1 commandTimeout, IDbTransaction transaction, ICache cache, ITrace trace, CancellationToken cancellationToken, String tableName, Boolean skipCommandArrayParametersCheck)
Schema and Model:
I have provided an example repository demonstrating the issue and the workaround here:
https://github.com/FrankHoogmans/RepoDbParameterTypeMappingIssue
Library Version:
RepoDb.SqlServer v1.13.1
Current workaround:
As a workaround, I have named the parameter differently, but this is an easy thing to miss and, in our case, didn't fail always since the input value is actually convertible to the specific type discovered in most cases.