我创建了一个基本的.Net Core Console测试应用程序,以连接到本地Sql Server实例并检索数据。以.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时也将按预期检索数据),但是在调用Sql时控制台应用程序,我收到以下消息:
服务器正在尝试使用不具有的功能
在此平台上受支持。在以下期间收到了不受支持的令牌“ Udt”
从服务器读取数据。
在System.Data.SqlClient.TdsParser.TryCommonProcessMetaData(TdsParserStateObject
stateObj,_SqlMetaData col)在
System.Data.SqlClient.TdsParser.TryProcessMetaData(Int32 cColumns,
TdsParserStateObject stateObj,_SqlMetaDataSet&metaData),位于
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,
SqlCommand cmdHandler,SqlDataReader dataStream,
BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject
stateObj,Boolean&dataReady)
System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()在
System.Data.SqlClient.SqlDataReader.get_MetaData()在
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,
RunBehavior runBehavior,字符串resetOptionsString)在
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior
cmdBehavior,RunBehavior,runBehavior,布尔returnStream,布尔
异步,Int32超时,任务和任务,布尔asyncWrite,SqlDataReader
ds)
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior
行为,String方法)在
System.Data.SqlClient.SqlCommand.ExecuteReader()位于
SqlServerTests.Program.Main(String [] args)在...
我假设在.Net Core应用程序中使用此代码时错过了一些东西,但我只是找不到。
最佳答案
查看SqlClient源代码,似乎仍然非常不支持UDT。在我的情况下,我试图插入包含HierarchyId列的记录。我收到“服务器正在尝试使用此平台不支持的功能。”从TdsParser。
该类(当前)在这里:
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
CONVERT(varchar(8000), [HierarchyColumn])
至少成功返回了字符串表示形式。这是有道理的,它不像我们可以访问现有的UDT类(如SqlHierarchyId)。
如果更改原始的
StringBuilder statement = new StringBuilder("SELECT * FROM calendars as i WHERE i.Id='[id]");
,以便SELECT语句显式引用这些列,并且还对UDT列执行转换,则应该得到一些更有用的东西。