在 .NET Core 中使用 NTS 几何体批量插入

Bulk Insert with NTS geometries in .NET Core

您可能知道,当您尝试插入大量行时,将数据插入 table "Entity Framework"-way 的速度非常慢。另一种方法是使用 SqlBulkCopy,它在提高性能方面做得很好。问题是 SqlBulkCopy(根据我阅读和测试的内容)不支持 .NET Core 中的 SQL 几何类型。

这是在 EF Core 中,C# 属性 类型是无法更改的 NTS 几何体。

使用旧库 Microsoft.SqlServer.Types 不是一种选择,因为它们在 .NET Core 中不起作用。数据当前作为 NTS 几何从另一个 SQL 服务器数据库加载。

有没有人找到插入多行的有效方法?

免责声明:我是Entity Framework Extensions

的所有者

As you probably know inserting data into a table the "Entity Framework"-way is incredibly slow

没错,这就是我们创建图书馆(付费图书馆)的主要原因。

我们的库支持 context.BulkInsert 到 Entity Framework,也支持 SQL Geometries


也就是说,这也可以通过 SqlBulkCopy 直接完成。

对于 EF Core,您需要使用 SqlServerBytesWriter.

转换您的值

这是一个完整的例子:

var list = // your list

var byteWriterGeometry = new NetTopologySuite.IO.SqlServerBytesWriter();
var byteWriterGeographgy = new NetTopologySuite.IO.SqlServerBytesWriter() { IsGeography = true };

var dt = new DataTable();
dt.Columns.Add("Geometry", typeof(object));
dt.Columns.Add("Point", typeof(object));

list.ForEach(x =>
{
    dt.Rows.Add(byteWriterGeometry.Write(x.Geometry), byteWriterGeographgy.Write(x.Point));
});

var connection = new SqlConnection("your connection string");

connection.Open();

var bulkCopy = new SqlBulkCopy(connection);
bulkCopy.DestinationTableName = "your table name";

bulkCopy.ColumnMappings.Add("Geometry", "Geometry");
bulkCopy.ColumnMappings.Add("Point", "Point");              

bulkCopy.WriteToServer(dt);

免责声明:我是 linq2db 和扩展 linq2db.EntityFrameworkCore

的创建者之一

linq2db 本身与 NetTopologySuite 没有依赖关系,因此库应该知道如何转换此类类型。每个应用程序配置 ONCE(我希望涵盖所有内容):

var writer = new NetTopologySuite.IO.SqlServerBytesWriter() { IsGeography = true };

MappingSchema.Default.SetConverter<Point, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<Polygon, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<GeometryCollection, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<LinearRing, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<LineString, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<MultiLineString, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<MultiPoint, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));
MappingSchema.Default.SetConverter<MultiPolygon, DataParameter>(p => new DataParameter(null, writer.Write(p), DataType.Udt));

然后您可以对具有任何几何体的任何实体使用 BulkCopy 属性:

context.BulkCopy(someEntities);