我有以下代码段:
var matchingAuthors = from authors in DB.AuthorTable
where m_authors.Keys.Contains(authors.AuthorId)
select authors;
foreach (AuthorTableEntry author in matchingAuthors)
{
....
}
其中m_authors
是包含“作者”条目的词典,DB.AuthorTable
是SQL表。当m_authors的大小超过某个值(大约在3000个条目标记处)时,我得到一个例外:
System.Data.SqlClient.SqlException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect.
Too many parameters were provided in this RPC request. The maximum is 2100.
有什么方法可以绕过这个并使用更大的字典吗?或者,是否有更好的方法来获取SQL表中的所有行,其中该行的特定列值与其中一个字典条目匹配?
答案 0 :(得分:2)
LINQ to SQL使用参数化IN
语句来执行本地Contains()
:
...
WHERE AuthorId IN (@p0, @p1, @p2, ...)
...
因此,您看到的错误是SQL用完了您的密钥所用的参数。我可以想到两个选择:
使用LINQ to Objects选择整个表和过滤器。
从密钥生成表达式树:请参阅Option 2 here。
答案 1 :(得分:0)
另一种选择是考虑如何填充m_authors以及是否可以将其作为查询元素本身包含在查询中,以便它变成服务器端的join / subselect。
答案 2 :(得分:0)
根据您的要求,您可以将工作拆分为多个较小的块(第一千,第二千等)。如果您的数据是读写且频繁更改,则会运行某些风险,但它可能会给您一些更好的可扩展性,除了在一大桶中拉回数千行之外。而且,如果您的数据可以部分处理(即没有将整个集合放在内存中),您可以在撤回下一个块时发送一个块来处理单独的线程。