在 .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);
您可能知道,当您尝试插入大量行时,将数据插入 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);