2

您可能知道,当您尝试插入大量行时,以“实体框架”方式将数据插入表中非常慢。另一种方法是使用 SqlBulkCopy,它在提高性能方面做得很好。问题是 SqlBulkCopy(根据我的阅读和测试)不支持 .NET Core 中的 SQL 几何类型。

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

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

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

4

2 回答 2

2

免责声明:我是实体框架扩展的所有者

您可能知道将数据插入表中的“实体框架”方式非常慢

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

我们的库context.BulkInsert通过实体框架支持并且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);
于 2021-07-14T12:28:48.843 回答
2

免责声明:我是linq2db和扩展linq2db.EntityFrameworkCore的创建者之一

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

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任何具有 Geometry 属性的实体:

context.BulkCopy(someEntities);
于 2021-07-14T15:13:04.423 回答