加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

LINQ参数过多时的解决方案

发布时间:2020-12-12 15:43:17 所属栏目:MsSql教程 来源:网络整理
导读:在项目中曾有这样的应用,权限筛选时先组织出员工的id,然后使用LINQ在相应的表中查询数据,条件是这些查询出来的数据的id必须在刚才权限筛选出来的id中,但是如果权限中的id太多,就会出现问题“传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。

在项目中曾有这样的应用,权限筛选时先组织出员工的id,然后使用LINQ在相应的表中查询数据,条件是这些查询出来的数据的id必须在刚才权限筛选出来的id中,但是如果权限中的id太多,就会出现问题“传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。此 RPC 请求中提供了过多的参数。最多应为 2100”。我推断可能是SQLServer中使用参数不能超过2100的原因。以上描述请看下边的例子。

?

int []?inputList? = ? new ? int [ 2100 ];
????????????
for ?( int ?i? = ? 0 ;?i? < ?inputList.Length;?i ++ )
????????????{
????????????????inputList[i]?
= ?i;
????????????}
????????????DataClasses1DataContext?dc?
= ? new ?DataClasses1DataContext();
????????????var?t
= (from?x? in ?dc.test1
??????????????????select?x).Where(c
=> inputList.Contains(c.testID));


????????????dc.Log?
= ?Console.Out;
????????????
foreach ?(var?item? in ?t)
????????????{
????????????????Console.WriteLine(item.testID);
????????????}

运行以上代码会报“传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。此 RPC 请求中提供了过多的参数。最多应为 2100”异常,如果将inputList数组大小改为5,执行的sql如下:
SELECT [t0].[testID],[t0].[testContent],[t0].[p]
FROM [dbo].[test1] AS [t0]
WHERE [t0].[testID] IN (@p0,@p1,@p2,@p3,@p4)
现在问题是如果超过2100个参数怎么办,我没想出用linq实现的好办法,这里使用了一个折中的办法

?

public ? static ?List < T > ?test < T > ()
????????{
????????????DataClasses1DataContext?dc?
= ? new ?DataClasses1DataContext();
????????????dc.Log?
= ?Console.Out;
????????????
int []?inputList? = ? new ? int [ 2100 ];
????????????StringBuilder?sqlstr?
= ? new ?StringBuilder( " select?*?from? " );
????????????sqlstr.Append(
typeof (T).Name);
????????????sqlstr.Append(
" ?where?testid?in?( " );
????????????
for ?( int ?i? = ? 0 ;?i? < ?inputList.Length;?i ++ )
????????????{
????????????????sqlstr.Append(i);
????????????????
if ?(i? < ?inputList.Length? - ? 1 )
????????????????{
????????????????????sqlstr.Append(
" , " );
????????????????}
????????????????
else
????????????????{
????????????????????sqlstr.Append(
" ) " );
????????????????}
????????????}?????????
????????????SqlCommand?cmd?
= ? new ?SqlCommand(sqlstr.ToString(),?(SqlConnection)dc.Connection);
????????????dc.Connection.Open();
????????????SqlDataReader?dr?
= ?cmd.ExecuteReader();
????????????List
< T > ?t? = ?dc.Translate < T > (dr).ToList();
????????????
return ?t;
????????}
static ? void ?Main( string []?args)
????????{
????????List
< test1 > ?l? = ?MyClass.test < test1 > ();
????????????
foreach ?(var?item? in ?l)
????????????{
????????????????Console.WriteLine(item.testID);
????????????}

}

?

这里利用了反射得到表名,然后利用Linq中的Translate方法将SqlDataReader转换成相应的类。

如果inputList不是一个数组而是一个IQueryable,直接用就没什么问题

?

var?tt? = ?(from?x? in ?dc.test
???????????????????????select?x.testid);
????????????var?t?
= ?from?x? in ?dc.log
????????????????????
where ?tt.Contains < int ?> (x.logId)
????????????????????select?x;

????????????dc.Log?
= ?Console.Out;
????????????
foreach ?(var?item? in ?t)
????????????{
????????????????Console.WriteLine(item.logMessage);
????????????}

拼接出的sql语句如下:

SELECT [t0].[logId],[t0].[logMessage],[t0].[x]
FROM [dbo].[log] AS [t0]
WHERE EXISTS(
??? SELECT NULL AS [EMPTY]
??? FROM [dbo].[test] AS [t1]
??? WHERE [t1].[testid] = ([t0].[logId])
??? )

?

转自:http://www.cnblogs.com/nuaalfm/archive/2008/08/10/1264796.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读