MySqlConnector
MySqlConnector copied to clipboard
System.InvalidProgramException: Common Language Runtime detected an invalid program.
trafficstars
Software versions MySqlConnector version: 2.3.6 Server type (MySQL, MariaDB, Aurora, etc.) and version: MYSQL .NET version: >.NET6 (Optional) ORM NuGet packages and versions:
Describe the bug System.InvalidProgramException: Common Language Runtime detected an invalid program. Exception Full exception message and call stack (if applicable)
2024-10-17 13:54:41,154 [39] INFO Core.ORM.MySqlAdapter - Connection Opened:
2024-10-17 13:54:41,155 [39] INFO Core.ORM.MySqlAdapter - Start Connection Execute with: CREATE TEMPORARY TABLE TmpIn_CMM_Role_Pages_6541bc52679842279c38e65b978d250b SELECT RoleID , PageName , USER_ACCESS , ADD_ACCESS , EDIT_ACCESS , DELETE_ACCESS , EXPORT_ACCESS , LAST_CHANGED_BY , LAST_CHANGED_ON FROM CMM_Role_Pages target LIMIT 0;:
2024-10-17 13:54:41,160 [39] ERROR Core.ORM.MySqlAdapter - Catch 2: System.InvalidProgramException: Common Language Runtime detected an invalid program.
at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 108
at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action`2 paramReader) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2827
at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) in C:\projects\dapper\Dapper\SqlMapper.cs:line 570
at Core.ORM.MySqlAdapter.BulkUpsert[T](IDbConnection connection, IDbTransaction transaction, IEnumerable`1 data, String tableName, Type type, Int32 bulkCopyTimeout, Nullable`1 commandTimeout):
2024-10-17 13:54:41,161 [39] ERROR OCM.Utilities.SqlDataAccess - ExecuteBulkUpsertQuery:System.InvalidProgramException: Common Language Runtime detected an invalid program.
at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 108
at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action`2 paramReader) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2827
at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) in C:\projects\dapper\Dapper\SqlMapper.cs:line 570
at Core.ORM.MySqlAdapter.BulkUpsert[T](IDbConnection connection, IDbTransaction transaction, IEnumerable`1 data, String tableName, Type type, Int32 bulkCopyTimeout, Nullable`1 commandTimeout)
at Core.ORM.DapperExtensions.BulkUpsert[T](IDbConnection connection, IEnumerable`1 data, IDbTransaction transaction, Int32 batchSize, Int32 bulkCopyTimeout, Nullable`1 commandTimeout)
at OCM.Utilities.SqlDataAccess.ExecuteBulkUpsertQuery[T](IEnumerable`1 obj)
Code sample
public void BulkUpsert<T>(IDbConnection connection, IDbTransaction transaction, IEnumerable<T> data, string tableName, Type type, int bulkCopyTimeout, int? commandTimeout)
{
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
var columns = PropertiesCache.GetColumnNamesCache(type);
var allPropertiesExceptComputed = allProperties.Except(computedProperties).ToList();
//var tempToBeInserted = $"TempInsert_{tableName}_{Guid.NewGuid().ToString("N")}".Replace(".", string.Empty);
var tempToBeInserted = $"TmpIn_{tableName}_{Guid.NewGuid().ToString("N")}".Replace(".", string.Empty);
tempToBeInserted = tempToBeInserted.Substring(0, Math.Min(tempToBeInserted.Length, 64));
var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
var mergingProperties = PropertiesCache.MergeConditionPropertiesCache(type);
string tempSql = $@"CREATE TEMPORARY TABLE {tempToBeInserted} SELECT { GetColumnsStringSqlServer(allPropertiesExceptComputed, columns)} FROM {tableName} target LIMIT 0;";
var con = new MySqlConnection(connection.ConnectionString);
if (!con.ConnectionString.ToLower().Replace(" ", "").Contains("allowloadlocalinfile=true"))
{
con.ConnectionString += ";allowloadlocalinfile = true;";
}
var bulkCopy = new MySqlBulkCopy(con, transaction as MySqlTransaction);
try
{
con.Open();
con.Execute(tempSql, null, transaction as MySqlTransaction, commandTimeout);
List<MySqlBulkCopyColumnMapping> colMappings = new List<MySqlBulkCopyColumnMapping>();
int i = 0;
foreach (var property in allPropertiesExceptComputed)
{
colMappings.Add(new MySqlBulkCopyColumnMapping(i, property.Name));
i++;
}
bulkCopy.BulkCopyTimeout = bulkCopyTimeout;
//bulkCopy.BatchSize = batchSize;
bulkCopy.DestinationTableName = tempToBeInserted;
var dataReader = ToDataTable(data, allPropertiesExceptComputed).CreateDataReader();
bulkCopy.WriteToServer(dataReader);
string mergeCondition = string.Join(" AND ", mergingProperties.Select(c => $"{columns[c.Name]}={columns[c.Name]} "));
string executeStatement = $@"
REPLACE INTO {tableName} ({GetColumnsStringSqlServer(allPropertiesExceptKeyAndComputed, columns)})
SELECT {GetColumnsStringSqlServer(allPropertiesExceptKeyAndComputed, columns)} FROM {tempToBeInserted}
WHERE ({mergeCondition});
DROP TABLE {tempToBeInserted};";
con.Execute(executeStatement, null, transaction as MySqlTransaction, commandTimeout);
}
catch (MySqlException ex)
{
if (ex.Message.Contains("Received an invalid column length from the bcp client for colid"))
{
string pattern = @"\d+";
Match match = Regex.Match(ex.Message.ToString(), pattern);
var index = Convert.ToInt32(match.Value) - 1;
FieldInfo fi = typeof(MySqlBulkCopy).GetField("_sortedColumnMappings", BindingFlags.NonPublic | BindingFlags.Instance);
var sortedColumns = fi.GetValue(bulkCopy);
var items = (Object[])sortedColumns.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sortedColumns);
FieldInfo itemdata = items[index].GetType().GetField("_metadata", BindingFlags.NonPublic | BindingFlags.Instance);
var metadata = itemdata.GetValue(items[index]);
var column = metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
var length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
throw new Exception(String.Format("Column: {0} contains data with a length greater than: {1}", column, length));
}
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}
Expected behavior A clear and concise description of what you expected to happen.
Additional context