将空列表或空值绑定到存储过程(.NET)上的表值参数
我创建了一个存储过程,该存储过程接受一个表值参数,该参数是一个具有将空列表或空值绑定到存储过程(.NET)上的表值参数,.net,sql-server-2008,stored-procedures,table-valued-parameters,.net,Sql Server 2008,Stored Procedures,Table Valued Parameters,我创建了一个存储过程,该存储过程接受一个表值参数,该参数是一个具有int类型的单列的表。其思想是简单地将ID列表传递到存储过程中,并允许存储过程处理数据。但是,在没有数据可传递的情况下,我会遇到问题(当我有数据时,事情会正常工作)。我正在将列表转换为IEnumerable,并将其绑定到存储过程的表值参数。我试图绑定一个空的列表,这导致了错误: System.ArgumentException:SqlDataRecord枚举中没有记录。要发送没有行的表值参数,请改为使用该值的null引用 然后我尝
int
类型的单列的表。其思想是简单地将ID列表传递到存储过程中,并允许存储过程处理数据。但是,在没有数据可传递的情况下,我会遇到问题(当我有数据时,事情会正常工作)。我正在将列表
转换为IEnumerable
,并将其绑定到存储过程的表值参数。我试图绑定一个空的列表
,这导致了错误:
System.ArgumentException:SqlDataRecord枚举中没有记录。要发送没有行的表值参数,请改为使用该值的null引用
然后我尝试绑定一个空值(我认为这就是上面消息的目的),但这只会导致另一个错误消息
System.NotSupportedException:不支持参数“@MainItemIdList”的DBNull值。表值参数不能为DBNull
在存储过程声明中,似乎不能将表值参数声明为null。将空列表绑定到at表值参数的正确方法是什么?诀窍是:根本不要传入参数。表值参数的默认值为空表
很遗憾,异常消息没有什么帮助。我对“不传递参数”语句的含义有点困惑。实体框架ExecuteSqlCommandAsync()的最终效果是:
这将以“默认值”的形式传递参数。传递空的
IEnumerable
时会出现错误,但当我传递空的列表时,它可以正常工作。不传递值会起作用,但在我有多个表值参数要传递到过程中的情况下不会起作用。我解决这个问题的方法是在查询字符串中指定DEFAULT
。比如说,
string sqlQuery = "[dbo].[GetOrderData] @QueueId";
if (OrderIdList.Any())
{
sqlQuery = sqlQuery + ", @OrderIdList";
}
else
{
sqlQuery = sqlQuery + ", DEFAULT";
}
if (RegionIdList.Any())
{
sqlQuery = sqlQuery + ", @RegionIdList";
}
else
{
sqlQuery = sqlQuery + ", DEFAULT";
}
幸亏我找到了解决这个问题的方法。添加新答案或改进答案都不会有什么坏处。这些信息仍然是相关的,其他人会发现它很有用(这就是本网站的全部要点!)+1如果使用普通的旧表适配器,有没有办法做到这一点?TableAdapter为具有与SP相同签名的CLR代理函数模板,它需要一个非空值。传递null或DbNull.Value会引发错误。返回1。这正是我需要做的-经过测试,效果很好。+1非常感谢-确认这对于TVPs的SqlDataRecord
/SqlMetaData
方法也是有效的。那么,我如何更改代码以不传递参数呢?在我的例子中,我有5个TVPs参数,每个参数都可能是空的。我使用的代码如下:BenefitsItemsLinkCollection itemsCollection=newbenefitsitemslinkcollection();itemsCollection.AddRange(项目);itemsPar.Value=itemsCollection;itemsPar.TypeName=“siriusType\u BenefitLinkedItems”;对于空的项目数组,我应该在这里更改什么?不确定为什么它对您有效,但这对我根本不起作用。使用这种方法时,我得到了原始问题中的确切错误消息。这对我不起作用。无论传递IEnumerable还是List,我都会遇到相同的错误。
string sqlQuery = "[dbo].[GetOrderData] @QueueId";
if (OrderIdList.Any())
{
sqlQuery = sqlQuery + ", @OrderIdList";
}
else
{
sqlQuery = sqlQuery + ", DEFAULT";
}
if (RegionIdList.Any())
{
sqlQuery = sqlQuery + ", @RegionIdList";
}
else
{
sqlQuery = sqlQuery + ", DEFAULT";
}