gpt4 book ai didi

c# - 批量插入具有地理空间数据类型的表时出现 "Specified type is not registered"错误

转载 作者:行者123 更新时间:2023-11-30 12:23:05 25 4
gpt4 key购买 nike

我正在尝试使用 System.Data 程序集 (4.6.1) 中的 SqlBulkCopy 类批量插入具有地理空间数据类型的表,使用代码看起来大致像这样(改编自 https://github.com/MikaelEliasson/EntityFramework.Utilities ):

public void InsertItems<T>(IEnumerable<T> items, string schema, string tableName, IList<ColumnMapping> properties, DbConnection storeConnection, int? batchSize)
{
using (var reader = new EFDataReader<T>(items, properties))
{
var con = (SqlConnection)storeConnection;
if (con.State != ConnectionState.Open)
{
con.Open();
}
using (var copy = new SqlBulkCopy(con))
{
copy.BatchSize = batchSize ?? 15000; //default batch size
if (!string.IsNullOrWhiteSpace(schema))
{
copy.DestinationTableName = $"[{schema}].[{tableName}]";
}
else
{
copy.DestinationTableName = "[" + tableName + "]";
}

copy.NotifyAfter = 0;

foreach (var i in Enumerable.Range(0, reader.FieldCount))
{
copy.ColumnMappings.Add(i, properties[i].NameInDatabase);
}
copy.WriteToServer(reader); // <-- throws here
copy.Close();
}
}
}

效果很好,直到我尝试在包含地理空间数据的表格上使用它。当我这样做时,出现以下错误:

ERROR Swyfft.Console.TaskManager - Error running task SeedRating: 
(InvalidOperationException) The given value of type DbGeography from the data source cannot be converted to type udt of the specified target column.;
(ArgumentException) Specified type is not registered on the target server.System.Data.Entity.Spatial.DbGeography, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.;
at Swyfft.Data.Utilities.SqlQueryProvider.InsertItems[T](IEnumerable`1 items, String schema, String tableName, IList`1 properties, DbConnection storeConnection, Nullable`1 batchSize) in C:\source\swyfft\swyf-website\Swyfft.Data.Utilities\SqlQueryProvider.cs:line 78
at Swyfft.Data.Utilities.EFBatchOperation`2.InsertAll[TEntity](IEnumerable`1 items, DbConnection connection, Nullable`1 batchSize) in C:\source\swyfft\swyf-website\Swyfft.Data.Utilities\EFBatchOperation.cs:line 138
at Swyfft.Data.Rating.RatingContext.BulkInsert[T](IEnumerable`1 entities, Nullable`1 batchSize) in C:\source\swyfft\swyf-website\Swyfft.Data.Rating\RatingContext.cs:line 69
at Swyfft.Seeding.CsvLoaders.CsvLoader.ProcessCsv[T](StreamReader streamReader, String fileName, ISwyfftContext ctx, Func`2 parserFunc) in C:\source\swyfft\swyf-website\Swyfft.Seeding\CsvLoaders\CsvLoader.cs:line 133
at Swyfft.Seeding.CsvLoaders.CsvLoader.InitializeCountyBlockQualities(String stateFilter) in C:\source\swyfft\swyf-website\Swyfft.Seeding\CsvLoaders\InitializeCountyBlockQualities.cs:line 35

我用 Google 搜索了一下,没有太大用处。我已经追踪到调用链,深入到 SqlBulkCopy 程序集的内部(感谢 Resharper!),但错误似乎隐藏得比我能够挖掘的更深。我已经尝试安装(并加载)适当的 SQL Server 类型包 ( https://www.nuget.org/packages/Microsoft.SqlServer.Types/ ),但没有成功。

有什么建议吗?

最佳答案

好的,我想我已经修好了。有问题的代码在 EFDataReader<T> 中类(我从 https://github.com/MikaelEliasson/EntityFramework.Utilities/blob/master/EntityFramework.Utilities/EntityFramework.Utilities/EFDataReader.cs 借来的)。它的GetValue(int ordinal)最初看起来像这样:

public override object GetValue(int ordinal)
{
return Accessors[ordinal](Enumerator.Current);
}

但这意味着它返回任何与数据库无关的 DbGeometryDbGeography恰好通过 DbGeometry 获得的值和 DbGeography ,SqlBulkCopy 类不理解。它们实际上需要特定于 SQL-Server,即 SqlGeographySqlGeometry ,像这样:

public override object GetValue(int ordinal)
{
object value = Accessors[ordinal](Enumerator.Current);

var dbgeo = value as DbGeography;
if (dbgeo != null)
{
var chars = new SqlChars(dbgeo.WellKnownValue.WellKnownText);
return SqlGeography.STGeomFromText(chars, dbgeo.CoordinateSystemId);
}

var dbgeom = value as DbGeometry;
if (dbgeom != null)
{
var chars = new SqlChars(dbgeom.WellKnownValue.WellKnownText);
return SqlGeometry.STGeomFromText(chars, dbgeom.CoordinateSystemId);
}

return value;
}

关于c# - 批量插入具有地理空间数据类型的表时出现 "Specified type is not registered"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38407683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com