在 CoreFx 上使用 System.Data.SqlClient 时出现 UDT 不支持的令牌问题
UDT Unsupported Token Issue when using System.Data.SqlClient on CoreFx
我已经创建了一个基本的 .Net Core 控制台测试应用程序来连接到本地 Sql 服务器实例并检索数据。相同的代码在以 .Net 4.6.1 为目标时工作正常,但在以 .Net Core 为目标时却不行:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Dynamic;
using System.Linq;
using System.Text;
namespace SqlServerTests
{
public class Program
{
public static void Main(string[] args)
{
try
{
StringBuilder statement = new StringBuilder("SELECT * FROM calendars as i WHERE i.Id='[id]");
SqlConnection sqlConnection = new SqlConnection("[Connection works fine]");
sqlConnection.Open();
SqlCommand sqlCommand = new SqlCommand(statement.ToString(), sqlConnection);
SqlDataReader sqlReader = sqlCommand.ExecuteReader();
if (!sqlReader.HasRows)
Console.WriteLine("No data found"); ;
List<dynamic> dataSet = new List<dynamic>();
if (sqlReader.HasRows)
while (sqlReader.Read())
{
dynamic dataObject = new ExpandoObject();
var data = dataObject as IDictionary<string, object>;
for (int i = 0; i < sqlReader.FieldCount; i++)
data[sqlReader.GetName(i)] = !sqlReader.IsDBNull(i) ? sqlReader.GetValue(i) : null;
dataSet.Add(data);
}
Console.WriteLine(dataSet.FirstOrDefault());
sqlConnection.Close();
}
catch(Exception exception)
{
//Exception code omitted
}
}
}
}
连接有效(另一个应用程序使用相同的连接来保存数据),并且当 运行 Sql Server Profiler 查询按预期执行(粘贴查询时也按预期检索数据到 Sql Server Management Studio),但是在控制台应用程序上调用 ExecuteReader 时,我收到以下消息:
The server is attempting to use a feature that is not
supported on this platform. Received an unsupported token 'Udt' while
reading data from the server.
at System.Data.SqlClient.TdsParser.TryCommonProcessMetaData(TdsParserStateObject
stateObj, _SqlMetaData col) at
System.Data.SqlClient.TdsParser.TryProcessMetaData(Int32 cColumns,
TdsParserStateObject stateObj, _SqlMetaDataSet& metaData) at
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,
SqlCommand cmdHandler, SqlDataReader dataStream,
BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject
stateObj, Boolean& dataReady) at
System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at
System.Data.SqlClient.SqlDataReader.get_MetaData() at
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,
RunBehavior runBehavior, String resetOptionsString) 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.ExecuteReader(CommandBehavior
behavior, String method) at
System.Data.SqlClient.SqlCommand.ExecuteReader() at
SqlServerTests.Program.Main(String[] args) in...
我假设我在 .Net Core 应用程序中使用此代码时遗漏了一些东西,但我就是找不到什么。
查看 SqlClient 源代码,UDT 似乎仍然不受支持。在我的情况下,我试图插入一条包含 HierarchyId 列的记录。我从 TdsParser 收到 'The server is attempting to use a feature that is not supported on this platform.'。
class(目前)在这里:
https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.cs
如果您搜索 SQLUDT,您会找到类似于以下内容的条目:
case TdsEnums.SQLUDT:
throw SQL.UnsupportedFeatureAndToken(_connHandler, SqlDbType.Udt.ToString());
这是 MyGet 包的来源:System.Data.SqlClient 4.1.1-beta-24222-02
更新: 通过以字符串表示形式发送 HierarchyId,我能够获得一个简单的插入语句以通过 Dapper 工作。 SqlBulkCopy 在此阶段仍然不可取。从读取的角度来看,如果我在 SELECT 语句中引用 HierarchyId 列,我会收到不受支持的异常。但是在SQL中使用SQL转换CONVERT(varchar(8000), [HierarchyColumn])
至少查询成功returns字符串表示。
这有点道理,它不像我们可以访问现有的 UDT classes 像 SqlHierarchyId。
如果您更改原始 StringBuilder statement = new StringBuilder("SELECT * FROM calendars as i WHERE i.Id='[id]");
以便 SELECT 语句显式引用列并对您的 UDT 列执行转换,您应该得到更有用的东西。
我已经创建了一个基本的 .Net Core 控制台测试应用程序来连接到本地 Sql 服务器实例并检索数据。相同的代码在以 .Net 4.6.1 为目标时工作正常,但在以 .Net Core 为目标时却不行:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Dynamic;
using System.Linq;
using System.Text;
namespace SqlServerTests
{
public class Program
{
public static void Main(string[] args)
{
try
{
StringBuilder statement = new StringBuilder("SELECT * FROM calendars as i WHERE i.Id='[id]");
SqlConnection sqlConnection = new SqlConnection("[Connection works fine]");
sqlConnection.Open();
SqlCommand sqlCommand = new SqlCommand(statement.ToString(), sqlConnection);
SqlDataReader sqlReader = sqlCommand.ExecuteReader();
if (!sqlReader.HasRows)
Console.WriteLine("No data found"); ;
List<dynamic> dataSet = new List<dynamic>();
if (sqlReader.HasRows)
while (sqlReader.Read())
{
dynamic dataObject = new ExpandoObject();
var data = dataObject as IDictionary<string, object>;
for (int i = 0; i < sqlReader.FieldCount; i++)
data[sqlReader.GetName(i)] = !sqlReader.IsDBNull(i) ? sqlReader.GetValue(i) : null;
dataSet.Add(data);
}
Console.WriteLine(dataSet.FirstOrDefault());
sqlConnection.Close();
}
catch(Exception exception)
{
//Exception code omitted
}
}
}
}
连接有效(另一个应用程序使用相同的连接来保存数据),并且当 运行 Sql Server Profiler 查询按预期执行(粘贴查询时也按预期检索数据到 Sql Server Management Studio),但是在控制台应用程序上调用 ExecuteReader 时,我收到以下消息:
The server is attempting to use a feature that is not supported on this platform. Received an unsupported token 'Udt' while reading data from the server. at System.Data.SqlClient.TdsParser.TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaData col) at System.Data.SqlClient.TdsParser.TryProcessMetaData(Int32 cColumns, TdsParserStateObject stateObj, _SqlMetaDataSet& metaData) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 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.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader() at SqlServerTests.Program.Main(String[] args) in...
我假设我在 .Net Core 应用程序中使用此代码时遗漏了一些东西,但我就是找不到什么。
查看 SqlClient 源代码,UDT 似乎仍然不受支持。在我的情况下,我试图插入一条包含 HierarchyId 列的记录。我从 TdsParser 收到 'The server is attempting to use a feature that is not supported on this platform.'。
class(目前)在这里: https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/TdsParser.cs
如果您搜索 SQLUDT,您会找到类似于以下内容的条目:
case TdsEnums.SQLUDT:
throw SQL.UnsupportedFeatureAndToken(_connHandler, SqlDbType.Udt.ToString());
这是 MyGet 包的来源:System.Data.SqlClient 4.1.1-beta-24222-02
更新: 通过以字符串表示形式发送 HierarchyId,我能够获得一个简单的插入语句以通过 Dapper 工作。 SqlBulkCopy 在此阶段仍然不可取。从读取的角度来看,如果我在 SELECT 语句中引用 HierarchyId 列,我会收到不受支持的异常。但是在SQL中使用SQL转换CONVERT(varchar(8000), [HierarchyColumn])
至少查询成功returns字符串表示。
这有点道理,它不像我们可以访问现有的 UDT classes 像 SqlHierarchyId。
如果您更改原始 StringBuilder statement = new StringBuilder("SELECT * FROM calendars as i WHERE i.Id='[id]");
以便 SELECT 语句显式引用列并对您的 UDT 列执行转换,您应该得到更有用的东西。