Description
Bug Description
If properties are mapped using quotes like Map("[field]")
or FluentMapper.Column("[field]")
, then when executing Insert or BulkInsert it throws an exception.
Exception Message on Insert:
Microsoft.Data.SqlClient.SqlException (0x80131904): Must declare the scalar variable "@IdFile".
at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at Microsoft.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at Microsoft.Data.SqlClient.SqlDataReader.get_MetaData()
at Microsoft.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
at Microsoft.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader(Boolean isInternal, Boolean forDescribeParameterEncryption)
at Microsoft.Data.SqlClient.SqlCommand.InternalEndExecuteReader(IAsyncResult asyncResult, Boolean isInternal, String endMethod)
at Microsoft.Data.SqlClient.SqlCommand.EndExecuteReaderInternal(IAsyncResult asyncResult)
at Microsoft.Data.SqlClient.SqlCommand.EndExecuteReaderAsync(IAsyncResult asyncResult)
at Microsoft.Data.SqlClient.SqlCommand.EndExecuteReaderAsyncCallback(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location ---
at RepoDb.DbConnectionExtension.InsertAsyncInternalBase[TEntity,TResult](IDbConnection connection, String tableName, TEntity entity, IEnumerable`1 fields, String hints, Nullable`1 commandTimeout, String traceKey, IDbTransaction transaction, ITrace trace, IStatementBuilder statementBuilder, CancellationToken cancellationToken) in /var/home/dyskette/Proyectos/github/RepoDB/RepoDb.Core/RepoDb/Operations/DbConnection/Insert.cs:line 772
Exception Message on BulkInsert:
System.MissingFieldException: There are no field(s) found for this operation.
at RepoDb.SqlConnectionExtension.BulkInsertAsyncInternalBase[TEntity](SqlConnection connection, String tableName, IEnumerable`1 entities, IEnumerable`1 mappings, SqlBulkCopyOptions options, String hints, Nullable`1 bulkCopyTimeout, Nullable`1 batchSize, Nullable`1 isReturnIdentity, Nullable`1 usePhysicalPseudoTempTable, SqlTransaction transaction, CancellationToken cancellationToken) in /var/home/dyskette/Proyectos/github/RepoDB/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkInsert.cs:line 500
Basically both errors happen because the comparison between FieldCache.Get
result and DbField.Cache
result don't match. The former has the quotes I added, the latter fetches the fields without the quotes.
Which means that on Insert
, it doesn't remove the identity from the InsertableFields
variable here. And on BulkInsert
it removes all fields that don't match, which is all of them, here.
In retrospective, I find it silly to be using quotes for the properties now. But, I just copied and pasted the names with quotes as they were generated by the Azure Data Studio and didn't think anything of it. It never crossed my mind that I was doing something wrong there. I was going in circles until I downloaded the source code, added it as references to my project and debugged it. 😢
Schema and Model:
CREATE TABLE [dbo].[NasFile]
(
[IdFile] INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
[FilePath] NVARCHAR(500) NULL,
);
Model that corresponds the schema.
[Map("[dbo].[NasFile]")]
public class BusinessFile
{
/// <summary>
/// Id of file
/// </summary>
[Map("[IdFile]")]
public int Id { get; set; }
/// <summary>
/// Path of the file in NAS
/// </summary>
[Map("[FilePath]")]
public string? Path { get; set; }
}
Library Version:
- RepoDb v1.13.1
- RepoDb.SqlServer v1.13.1
- RepoDb.SqlServer.BulkOperations v1.13.1