Thursday 26 April 2012

[Fixed]How to overcome the linq contains limitation.Too many parameters were provided in this RPC request. the maximum is 2100

When we want to filter the data from the Linq to Sql query with the collection every one is trying to use the Contains() operator as follows. Linq to Sql will try to generate a sql query to represent the whole expression. This means that it will try to pass in the collection as parameters to a sql query. If there are too many parameters the query will hit the parameter limit (2100) and it cannot be executed. If there are not that many parameters, then you can use a contains expression which will be converted to an "IN" expression in sql. Sample code as follows
List<int> contactIds=Contact.GetContactIds()
//count of contactIds is morethan 2100
var contacts = Context.Contacts.Where(c => contactIds.Contains(c.ContactId)).ToList();
If the parameter limit exeeds then the following exception throws.
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.
To avoid this many developers will try to join the in memory collection with database table as follows. 
List<int> contactIds=Contact.GetContactIds()
//count of contactIds is morethan 2100
var contacts = Context.Contacts.Join(contactIds, c => c.ContactId, ci => ci, (c, ci) => c).ToList();
When developer trying this the following exception throws.
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
This means that the linq to sql generates sql query and executes on the database server. Our in memory collection will not support to execute on the database server. so will get the above exception.
The easiest resolution is to convert the LINQ to SQL table into an IEnumerable list, which can be done as follows.
List<int> contactIds=Contact.GetContactIds()
//count of contactIds is morethan 2100
var contacts = Context.Contacts.AsEnumerable().Join(contactIds, c => c.ContactId, ci => ci, (c, ci) => c).ToList();
I hope this solution helps you.

1 comment:

  1. List contactIds=Contact.GetContactIds()
    //count of contactIds is morethan 2100
    var contacts = Context.Contacts.AsEnumerable().Join(contactIds, c => c.ContactId, ci => ci, (c, ci) => c).ToList();

    why we must use as enumerable instead of tolist? how about we use method take (2000). I think this solution is faster using as enumerable

    ReplyDelete