MySqlConnector icon indicating copy to clipboard operation
MySqlConnector copied to clipboard

BulkCopy does not work for Geometry Columns when they are first column in DataTable

Open mxcolin opened this issue 5 months ago • 0 comments

Software versions MySqlConnector version: 2.40 Server type (MySQL, MariaDB, Aurora, etc.) and version: MySQL 8.0.31.0 .NET version: 9 (Optional) ORM NuGet packages and versions: 2.40

Describe the bug When using MySqlBulkCopy, if the datatable that is sent contains a MySqlGeometry column as the first column it will throw an exception, all that's required to get around it is to add a dummy column in the datatable and increment the SourceColumn number in the mapping. However, this is a required work around or the below exception is thrown.

Exception MySqlConnector.MySqlException: 'Cannot get geometry object from data you send to the GEOMETRY field'

at MySqlConnector.Core.ServerSession.<ReceiveReplyAsync>d__117.MoveNext() at System.Threading.Tasks.ValueTask1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at MySqlConnector.Core.ResultSet.<ReadResultSetHeaderAsync>d__2.MoveNext() at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) at MySqlConnector.MySqlDataReader.<InitAsync>d__111.MoveNext() at MySqlConnector.Core.CommandExecutor.<ExecuteReaderAsync>d__0.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at MySqlConnector.MySqlCommand.<ExecuteNonQueryAsync>d__78.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at MySqlConnector.MySqlBulkLoader.<LoadAsync>d__73.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable1.ConfiguredValueTaskAwaiter.GetResult() at MySqlConnector.MySqlBulkCopy.<WriteToServerAsync>d__31.MoveNext() at System.Runtime.CompilerServices.ValueTaskAwaiter1.GetResult() at MySqlConnector.MySqlBulkCopy.WriteToServer(DataTable dataTable) at Program.<Main>$(String[] args) in C:\Users\colin\Projects\Velocity\src\Example\Program.cs:line 143

Code sample

/* A concise code sample to reproduce the bug */
var cs = "Server=hostname;Port=3306;User ID=userid;Password=password;Allow Load Local Infile=True;Allow User Variables=True";
var c = new MySqlConnection(cs);
c.Open();

var ct = "CREATE TABLE test_geog (geo_id BIGINT UNIQUE NOT NULL AUTO_INCREMENT, geo_data GEOMETRY SRID 4326 NOT NULL)";

var command = new MySqlCommand(ct, c);
command.ExecuteNonQuery();

var dt = new DataTable();

// Uncomment this line to add dummy column
//dt.Columns.Add("dummy", typeof(int));
dt.Columns.Add("geo_data", typeof(MySqlGeometry));

dt.Rows.Add([
    //1, 
    MySqlGeometry.FromWkb(4326, new Point(1, 1).ToBinary())
]);

var bc = new MySqlBulkCopy(c);
bc.DestinationTableName = "test_geog";

var mapping = new MySqlBulkCopyColumnMapping();

mapping.SourceOrdinal = 0;
// Will work if above lines uncommented and source ordinal increased, just can't be 0
// mapping.SourceOrdinal = 1;

mapping.DestinationColumn = "geo_data";
bc.ColumnMappings.Add(mapping);

bc.WriteToServer(dt);

Expected behavior There shouldn't be a need to add a dummy column.

Additional context I used NetTopologySuite for the Point class above so I could get WKB.

mxcolin avatar Apr 30 '25 04:04 mxcolin