.NET Core 2.1, SQL Server, UDT type, Exception: UdtTypeName property must be set for UDT parameters. #1349
Closed
Description
I am trying to use the spatial types in the Unofficial.Microsoft.SqlServer.Types
package. The following error occurs when trying to use an SqlGeography
or SqlGeometry
value in a query:
System.ArgumentException
HResult=0x80070057
Message=UdtTypeName property must be set for UDT parameters.
Source=System.Data.SqlClient
StackTrace:
at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
at System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters)
at System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc)
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.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at LinqToDB.Data.DataConnection.ExecuteNonQuery()
at LinqToDB.Linq.QueryRunner.NonQueryQuery(Query query, IDataContext dataContext, Expression expr, Object[] parameters)
at LinqToDB.Linq.QueryRunner.<>c__DisplayClass28_0.<SetNonQueryQuery>b__0(IDataContext db, Expression expr, Object[] ps)
at LinqToDB.Linq.ExpressionQuery`1.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
linq2db correctly sets SqlParameter.SqlDbType
to Udt
and SqlParameter.TypeName
to Geography
, however, it does not set SqlParameter.UdtTypeName
which causes the exception. The reason is the following code from the SqlServerDataProvider
class:
case DataType.Udt :
{
string s;
if (value != null && _udtTypes.TryGetValue(value.GetType(), out s))
if (parameter is SqlParameter)
#if NETSTANDARD1_6 || NETSTANDARD2_0
((SqlParameter)parameter).TypeName = s;
#else
((SqlParameter)parameter).UdtTypeName = s;
#endif
}
Steps to reproduce
I used SqlServerTools.AddUdtType
to register the types before opening a connection.
SqlServerTools.AddUdtType<SqlGeography>("Geography", null, LinqToDB.DataType.Udt);
SqlServerTools.AddUdtType<SqlGeometry>("Geometry", null, LinqToDB.DataType.Udt);
using (var db = new Database(...))
{
var value = new SqlGeographyBuilder();
value.BeginGeography(OpenGisGeographyType.Point);
value.AddLine(1, 1);
value.EndGeography();
db.GeoValues
.Where(x => x.Id == -1)
.Set(x => x.Position, value.ConstructedGeography)
.Update();
}
Environment details
linq2db version: 2.4.0
Database Server: SQL Server 2016
Database Provider: Any SQL Server provider
Operating system: Windows 10
Framework version: .NET Core 2.1