Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当源是DataReader时,如何指定在表值参数中使用服务器定义的值?_C#_Sql Server_.net Core_Sqldatareader_Table Valued Parameters - Fatal编程技术网

C# 当源是DataReader时,如何指定在表值参数中使用服务器定义的值?

C# 当源是DataReader时,如何指定在表值参数中使用服务器定义的值?,c#,sql-server,.net-core,sqldatareader,table-valued-parameters,C#,Sql Server,.net Core,Sqldatareader,Table Valued Parameters,我的TVP看起来像这样: 创建类型p_tvp为表 ( id int标识不为空, 值浮动不为空 ) 我有一些datareader,它会生成一个double列表(不是实际执行的SQL): 使用(var conn=new SqlConnection(\u srcString) 使用(var cmd=new SqlCommand(“从(值(1e)、(2e)、(3e))f(v)中选择*,conn)) { 等待连接OpenAsync(); 使用(var rdr=await _cmd.ExecuteRead

我的TVP看起来像这样:

创建类型p_tvp为表
(
id int标识不为空,
值浮动不为空
)
我有一些datareader,它会生成一个double列表(不是实际执行的SQL):

使用(var conn=new SqlConnection(\u srcString)
使用(var cmd=new SqlCommand(“从(值(1e)、(2e)、(3e))f(v)中选择*,conn))
{
等待连接OpenAsync();
使用(var rdr=await _cmd.ExecuteReaderAsync())
使用(var tCon=new SqlConnection(_targetString))
使用(var tcmd=newsqlcommand(“MyStoredProcedure”,tCon))
{
等待tCon.OpenAsync();
tcmd.CommandType=CommandType.StoreProcedure;
var param=tcmd.Parameters.AddWithValue(@tvp,rdr);
param.SqlDbType=SqlDbType.Structured;
param.TypeName=“dbo.p_tpv”;
等待tcmd.ExecuteNonQuery();
}
}
我得到的错误是我没有足够的参数。因为我的目标TVP有2列。如果我添加一个伪列,我得到的错误是我无法将标识插入到表值参数中

我无法重新定义TVP


另一个问题指定一个
DataTable
作为源,答案使用
IEnumerable
。不幸的是,这两个问题都不能解决我使用
DbDataReader
的问题。如果需要,我可以转换为
SqlDataRecord
,但我想避免额外的步骤,因为我无法轻松控制
DbDataReader
source.

正如法比奥在对该问题的评论中所指出的,您可以使用
IEnumerable
通过
SqlDataRecord
设置自定义数据结构,然后将结果从
SqlDataReader
流式传输到TVP中

在下面的示例中,TVP的“id”列使用了
SqlMetaData
构造函数,该构造函数允许将
useServerDefault
设置为
true
。如果原始查询中没有返回任何行,
产量中断应该安全退出

private IEnumerable SendRowsToProc(SqlDataReader)
{
如果(!reader.HasRows)
{
屈服断裂;
}
SqlDataRecord resultRow=新的SqlDataRecord(新的SqlMetaData[]{
新的SqlMetaData(“id”,SqlDbType.Int,true,true,SortOrder.Unspecified,0),
新的SqlMetaData(“值”,SqlDbType.Float)
});
while(reader.Read())
{
resultRow.SetDouble(1,reader.GetDouble(0));
收益率收益率;
}
}
因此,不是将rdr作为TVP
SqlParameter
的“值”传入,而是传入:
SendRowsToProc(rdr)


另一个选项,如果您真的想通过<代码> RDR < /C> >作为TVP值:

  • 使用不同的UDTT,该UDTT具有相同的
    ID INT NOT NULL
    列,但未标记为
    标识
  • 选择
    语句(在源代码处)中,以以下内容开始列列表:

    ROW_NUMBER() OVER (ORDER BY @@MICROSOFTVERSION) AS [ID]
    

  • 这应该提供与
    IDENTITY
    列当前提供的功能相同的功能。当然,如果您正在执行存储过程,它将不起作用,但对于问题中给出的情况,它应该可以正常工作。

    正如Fabio在对问题的评论中指出的,您可以使用
    IEnumerable
    来设置自定义数据结构通过
    SqlDataRecord
    执行CTU,然后将结果从
    SqlDataReader
    流式传输到TVP

    在下面的示例中,TVP的“id”列使用了
    SqlMetaData
    构造函数,该构造函数允许将
    useServerDefault
    设置为
    true
    。如果原始查询中没有返回任何行,
    产量中断应该安全退出

    private IEnumerable SendRowsToProc(SqlDataReader)
    {
    如果(!reader.HasRows)
    {
    屈服断裂;
    }
    SqlDataRecord resultRow=新的SqlDataRecord(新的SqlMetaData[]{
    新的SqlMetaData(“id”,SqlDbType.Int,true,true,SortOrder.Unspecified,0),
    新的SqlMetaData(“值”,SqlDbType.Float)
    });
    while(reader.Read())
    {
    resultRow.SetDouble(1,reader.GetDouble(0));
    收益率收益率;
    }
    }
    
    因此,不是将rdr作为TVP
    SqlParameter
    的“值”传入,而是传入:
    SendRowsToProc(rdr)


    另一个选项,如果您真的想通过<代码> RDR < /C> >作为TVP值:

  • 使用不同的UDTT,该UDTT具有相同的
    ID INT NOT NULL
    列,但未标记为
    标识
  • 选择
    语句(在源代码处)中,以以下内容开始列列表:

    ROW_NUMBER() OVER (ORDER BY @@MICROSOFTVERSION) AS [ID]
    

  • 这应该提供与
    IDENTITY
    列当前提供的功能相同的功能。当然,如果您正在执行存储过程,它将不起作用,但对于问题中给出的情况,它应该可以。不过,您也可以使用读卡器来启用流。如果您使用数据表,则必须具体化数据我的实际源数据库不是Sql Server。是的,我这样做了。这又不是我的实际代码,但我会更新我的示例。这可能再次重复,这是一个数据表(实际答案通过
    IEnumerable
    实现。我有一个
    DbDataReader
    。你不能用DbDataReader来做这件事,你可以用“流”来实现DbDataReader进入
    IEnumerable
    。使用
    IEnumerable
    您将一次枚举一行,而不会将整个数据具体化。您也可以使用reader来启用流式处理。如果您使用datatable,则必须具体化数据集。我的实际源数据库不是Sql Server。是的,我这样做。这又不是我的actu所有代码,但我将更新我的示例。可能的重复,这是针对datatable(实际答案实现)