Подтвердить что ты не робот

Достижение предела параметра 2100 (SQL Server) при использовании Contains()

from f in CUSTOMERS
where depts.Contains(f.DEPT_ID)
select f.NAME

depts - список (IEnumerable<int>) идентификаторов отдела

Этот запрос работает нормально, пока вы не передадите большой список (скажем, около 3000 идентификаторов). Затем я получаю эту ошибку:

Неправильный поток протокола входящего потока табличных данных (TDS) удаленных процедур (RPC). Слишком много параметров было предоставлено в этом запросе RPC. Максимум 2100.

Я изменил свой запрос на:

var dept_ids = string.Join(" ", depts.ToStringArray());
from f in CUSTOMERS
where dept_ids.IndexOf(Convert.ToString(f.DEPT_id)) != -1
select f.NAME

используя IndexOf(), исправил ошибку, но сделал запрос медленным. Есть ли другой способ решить эту проблему? Большое спасибо.

4b9b3361

Ответ 1

Мое решение (Гиды → Список рекомендаций):

List<tstTest> tsts = new List<tstTest>();
for(int i = 0; i < Math.Ceiling((double)Guides.Count / 2000); i++)
{
    tsts.AddRange(dc.tstTests.Where(x => Guides.Skip(i * 2000).Take(2000).Contains(x.tstGuid)));
}
this.DataContext = tsts;

Ответ 2

Почему бы не написать запрос в sql и не прикрепить свою сущность?

Было немного, так как я работал в Linq, но здесь идет:

IQuery q = Session.CreateQuery(@"
         select * 
         from customerTable f
         where f.DEPT_id in (" + string.Join(",", depts.ToStringArray()) + ")");
q.AttachEntity(CUSTOMER);

Конечно, вам нужно будет защититься от инъекций, но это не должно быть слишком сложно.

Ответ 3

Вы захотите проверить проект LINQKit, так как внутри где-то есть метод для доработки таких утверждений для решения этой проблемы. Я считаю, что идея состоит в том, чтобы использовать PredicateBuilder, чтобы разбить локальную коллекцию на более мелкие фрагменты, но я не рассматривал это решение подробно, потому что вместо этого я искал более естественный способ справиться с этим.

К сожалению, из ответ Microsoft на мое предложение, чтобы исправить это поведение, нет планов установить, что это адресовано для .NET Framework 4.0 или даже последующих пакетов обновления.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=475984

UPDATE:

Я открыл дискуссию относительно того, будет ли это исправлено для LINQ to SQL или ADO.NET Entity Framework на форумах MSDN. Пожалуйста, просмотрите эти сообщения для получения дополнительной информации об этих темах и ознакомьтесь с временным обходным решением, которое я разработал с помощью XML и SQL UDF.

Ответ 4

У меня была схожая проблема, и у меня есть два способа исправить ее.

Чтобы получить значения, не являющиеся в списке, я использовал За исключением метода или левого соединения.