borisdj / EFCore.BulkExtensions

Entity Framework EF Core efcore Bulk Batch Extensions with BulkCopy in .Net for Insert Update Delete Read (CRUD), Truncate and SaveChanges operations on SQL Server, PostgreSQL, MySQL, SQLite

Home Page:https://codis.tech/efcorebulk

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SqlServerAdapter doesn't handle NetTopologySuite.Geometries.Point and other geometries

biegehydra opened this issue · comments

Version: 6.7.16

When trying to serialize a field like so public Point Location {get;set;}, I was getting this error.

  HResult=0x80070057
  Message=Type of value has a mismatch with column typeCouldn't store <POINT (-88.0958 30.2546)> in Location Column.  Expected type is Byte[].
  Source=System.Data.Common
  StackTrace:
   at System.Data.DataColumn.set_Item(Int32 record, Object value)
   at System.Data.DataTable.NewRecordFromArray(Object[] value)
   at System.Data.DataRowCollection.Add(Object[] values)
   at EFCore.BulkExtensions.SqlAdapters.MySql.MySqLAdapter.InnerGetDataTable[T](DbContext context, Type& type, IList`1 entities, TableInfo tableInfo)

I did some digging and it looks like the SqlServerAdapter has some issues with Geometries in InnerGetDataTable. If you walkthrough the propertiesToLoad loop, you can see that only the special case of the HeirarchyId is supported. When I walkthrough with a Point (no other types tested), propertyValue stays an instance of Point (doesn't get converted to byte[]) and the exception above is thrown.

I was able to solve this issue locally with these 2 changes.
Set the propertyType to MySqlGeometry: propertyType = typeof(MySqlGeometry);
Add special case for Geometries here, like SqlServerAdapter:

if (tableInfo.HasSpatialType && propertyValue is Geometry geometryValue)
{
    geometryValue.SRID = tableInfo.BulkConfig.SRID;
    var wkb = geometryValue.ToBinary();
    propertyValue = MySqlGeometry.FromWkb(geometryValue.SRID, wkb);
}

I would fix the rests of the code paths and add tests but I can't spend any more time on this. I hope this helps.

I have committed proposed enhancement since it does not affect regular usage.
Can you just add a sample for test when the exception you were getting happens, since I was not able to reproduce it.