根据MSDN,System.Data.SqlClient支持从DataTable,DbDataReader或IEnumerable< SqlDataRecord>填充表值参数.对象.
我编写了以下代码,这些代码使用IEnumerable< SqlDataRecord>填充了表值参数表对象:
static void Main()
{
List<int> idsToSend = ...
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(@"SELECT ...
FROM ...
INNER JOIN @ids mytable ON ...", connection);
command.Parameters.Add(new SqlParameter("@ids", SqlDbType.Structured)
{
TypeName = "int_list_type",
Direction = ParameterDirection.Input,
Value = GetSqlDataRecords(idsToSend) //returns IEnumerable<SqlDataRecord>
});
SqlDataReader reader = command.ExecuteReader();
//consume reader...
}
}
它运作完美.
MSDN页面显示:
You can also use any object derived from
DbDataReader
to stream rows
of data to a table-valued parameter.
我想使用自定义DbDataReader来传递行数据.像这样:
public class CustomDataReader : DbDataReader
{
public CustomDataReader(IEnumerable<int> values)
{
}
//implementation of other abstract methods and fields required by DbDataReader
//...
}
我在初始代码示例中更改了以下行:
Value = GetSqlDataRecords(idsToSend)
=>
Value = new CustomDataReader(idsToSend)
如果运行代码,则在执行command.ExecuteReader()时会出现以下异常:
An unhandled exception of type ‘System.NotSupportedException’ occurred
in System.Data.dll Additional information: Specified method is not
supported.
我在CustomDbDataReader类的所有方法和属性上都设置了一个断点:在得到异常之前没有一个方法被调用,因此它可能与DbDataReader的实现无关
编辑:这是根据要求的堆栈跟踪:
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(SqlCommand cmd, _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, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader()
at ConsoleApplication211.Program.Main() in Program.cs:line 51
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
解决方法:
您需要实现GetSchemaTable
,它没有标记为抽象.
另请参阅:How To Retrieve Column Schema by Using the DataReader GetSchemaTable Method and Visual C# .NET