如何使用linq2db插入sql地理?
How to use linq2db to insert sql geography?
真的很简单:
var a = SqlGeography.STGeomFromText(new SqlChars("POINT(-122.34900 47.65100)"), 4326);`
然后插入
await _geoDb.Table.Value(x => x.Geom, a) // Geom is of type SqlGeography
这给我错误:
System.ArgumentException: No mapping exists from object type
Microsoft.SqlServer.Types.SqlGeography to a known managed provider
native type.
我尝试使用 geography::STGeomFromText
手动插入,效果如预期。
映射为:
[Column("geom"), Nullable]
public SqlGeography Geom { get; set; } // geography
Table def.
create table municipal.country
(
id int identity
constraint PK_Canton
primary key,
geom geography
)
我正在使用 Microsoft.SqlServer.Types
这个 nuget dotMorten.Microsoft.SqlServer.Types.
Linq2Db 版本是:3.1.6(如果我更新到最新也是一样)。
更新
我能够通过安装 dotMorten.Microsoft.SqlServer.Types 1.5
并将自定义汇编指令添加到 Program.cs (https://linq2db.github.io/articles/FAQ.html#how-can-i-use-sql-server-spatial-types) 来解决这个问题。
它适用于简单的点,但在多多边形的情况下我收到此错误。
System.InvalidOperationException: Invalid operation. The connection is closed.
at System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte flushMode, Boolean canAccumulate)
at System.Data.SqlClient.TdsParserStateObject.WriteBytes(ReadOnlySpan`1 b, Int32 len, Int32 offsetBuffer, Boolean canAccumulate, TaskCompletionSource`1 completion, Byte[] array)
at System.Data.SqlClient.TdsParserStateObject.WriteByteArray(Byte[] b, Int32 len, Int32 offsetBuffer, Boolean canAccumulate, TaskCompletionSource`1 completion)
at System.Data.SqlClient.TdsParser.TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParameter param, MetaType mt, Byte options)
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource`1 completion, Int32 startRpc, Int32 startParam)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.BeginExecuteNonQuery(AsyncCallback callback, Object stateObject)
at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endFunction, Action`1 endAction, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory`1.FromAsync(Func`3 beginMethod, Func`2 endMethod, Object state)
at System.Data.SqlClient.SqlCommand.ExecuteNonQueryAsync(CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at LinqToDB.Data.RetryPolicy.RetryPolicyBase.ExecuteImplementationAsync[TResult](Func`2 operation, CancellationToken cancellationToken)
at LinqToDB.Data.DataConnection.ExecuteNonQueryAsync(CancellationToken cancellationToken)
at LinqToDB.Data.DataConnection.QueryRunner.ExecuteNonQueryAsync(CancellationToken cancellationToken)
at LinqToDB.Linq.QueryRunner.NonQueryQueryAsync(Query query, IDataContext dataContext, Expression expression, Object[] ps, Object[] preambles, CancellationToken cancellationToken)
at LinqToDB.Linq.QueryRunner.NonQueryQueryAsync(Query query, IDataContext dataContext, Expression expression, Object[] ps, Object[] preambles, CancellationToken cancellationToken)
at LinqToDB.Linq.ExpressionQuery`1.LinqToDB.Async.IQueryProviderAsync.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at LinqToDB.LinqExtensions.InsertAsync[T](IValueInsertable`1 source, CancellationToken token)
at GeoIndexer.Services.GeoIndexerService.IndexCantons(CancellationToken cancellationToken) in /Users/nikola/projects/immoledo/GeoIndexer/src/Geoindexer/Services/GeoIndexerService.cs:line 118
at GeoIndexer.GeoIndexerConsoleApp.<>c__DisplayClass5_0.<<StartAsync>b__1>d.MoveNext() in /Users/nikola/projects/immoledo/GeoIndexer/src/Geoindexer/GeoIndexerConsoleApp.cs:line 41
info: Microsoft.Hosting.Lifetime[0]
更新
它有效,如果我不使用 insertAsync
而只是 InsertWithInt32Identity
这取决于您使用哪个 SQL 服务器提供商。 linq2db
支持两个可用的 ADO.NET 供应商:
- 对于
System.Data.SqlClient
你必须使用
dotMorten.Microsoft.SqlServer.Types
1.5
,
- 对于
Microsoft.Data.SqlClient
使用 dotMorten.Microsoft.SqlServer.Types
2.5
真的很简单:
var a = SqlGeography.STGeomFromText(new SqlChars("POINT(-122.34900 47.65100)"), 4326);`
然后插入
await _geoDb.Table.Value(x => x.Geom, a) // Geom is of type SqlGeography
这给我错误:
System.ArgumentException: No mapping exists from object type Microsoft.SqlServer.Types.SqlGeography to a known managed provider native type.
我尝试使用 geography::STGeomFromText
手动插入,效果如预期。
映射为:
[Column("geom"), Nullable]
public SqlGeography Geom { get; set; } // geography
Table def.
create table municipal.country
(
id int identity
constraint PK_Canton
primary key,
geom geography
)
我正在使用 Microsoft.SqlServer.Types
这个 nuget dotMorten.Microsoft.SqlServer.Types.
Linq2Db 版本是:3.1.6(如果我更新到最新也是一样)。
更新
我能够通过安装 dotMorten.Microsoft.SqlServer.Types 1.5
并将自定义汇编指令添加到 Program.cs (https://linq2db.github.io/articles/FAQ.html#how-can-i-use-sql-server-spatial-types) 来解决这个问题。
它适用于简单的点,但在多多边形的情况下我收到此错误。
System.InvalidOperationException: Invalid operation. The connection is closed.
at System.Data.SqlClient.TdsParserStateObject.WritePacket(Byte flushMode, Boolean canAccumulate)
at System.Data.SqlClient.TdsParserStateObject.WriteBytes(ReadOnlySpan`1 b, Int32 len, Int32 offsetBuffer, Boolean canAccumulate, TaskCompletionSource`1 completion, Byte[] array)
at System.Data.SqlClient.TdsParserStateObject.WriteByteArray(Byte[] b, Int32 len, Int32 offsetBuffer, Boolean canAccumulate, TaskCompletionSource`1 completion)
at System.Data.SqlClient.TdsParser.TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParameter param, MetaType mt, Byte options)
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource`1 completion, Int32 startRpc, Int32 startParam)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.BeginExecuteNonQuery(AsyncCallback callback, Object stateObject)
at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endFunction, Action`1 endAction, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory`1.FromAsync(Func`3 beginMethod, Func`2 endMethod, Object state)
at System.Data.SqlClient.SqlCommand.ExecuteNonQueryAsync(CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at LinqToDB.Data.RetryPolicy.RetryPolicyBase.ExecuteImplementationAsync[TResult](Func`2 operation, CancellationToken cancellationToken)
at LinqToDB.Data.DataConnection.ExecuteNonQueryAsync(CancellationToken cancellationToken)
at LinqToDB.Data.DataConnection.QueryRunner.ExecuteNonQueryAsync(CancellationToken cancellationToken)
at LinqToDB.Linq.QueryRunner.NonQueryQueryAsync(Query query, IDataContext dataContext, Expression expression, Object[] ps, Object[] preambles, CancellationToken cancellationToken)
at LinqToDB.Linq.QueryRunner.NonQueryQueryAsync(Query query, IDataContext dataContext, Expression expression, Object[] ps, Object[] preambles, CancellationToken cancellationToken)
at LinqToDB.Linq.ExpressionQuery`1.LinqToDB.Async.IQueryProviderAsync.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at LinqToDB.LinqExtensions.InsertAsync[T](IValueInsertable`1 source, CancellationToken token)
at GeoIndexer.Services.GeoIndexerService.IndexCantons(CancellationToken cancellationToken) in /Users/nikola/projects/immoledo/GeoIndexer/src/Geoindexer/Services/GeoIndexerService.cs:line 118
at GeoIndexer.GeoIndexerConsoleApp.<>c__DisplayClass5_0.<<StartAsync>b__1>d.MoveNext() in /Users/nikola/projects/immoledo/GeoIndexer/src/Geoindexer/GeoIndexerConsoleApp.cs:line 41
info: Microsoft.Hosting.Lifetime[0]
更新
它有效,如果我不使用 insertAsync
而只是 InsertWithInt32Identity
这取决于您使用哪个 SQL 服务器提供商。 linq2db
支持两个可用的 ADO.NET 供应商:
- 对于
System.Data.SqlClient
你必须使用dotMorten.Microsoft.SqlServer.Types
1.5
, - 对于
Microsoft.Data.SqlClient
使用dotMorten.Microsoft.SqlServer.Types
2.5