传入的请求包含太多参数。 服务器最多支持2100个参数
我有这个看似简单的linq-to-sql查询,可以搜索多个列中的一些数据; 像这样的东西:
List TheTableIDs = list of IDs (sometimes more than 2100) var QueryOutput = (from x in TheDataContext.SomeTable where TheTableIDs.Contains(x.ID) && x.Col1.Contains(SomeString) || x.Col2.Contains(SomeString)) select x.ID).ToList();
我得到的错误是这样的:
附加信息:传入请求的参数太多。 服务器最多支持2100个参数。 减少参数数量并重新发送请求。
解决这个问题的最佳方法是什么?
我环顾四周,找到的解决方案看起来像这样:
var QueryOutput = TheDataContext.SomeTable.AsEnumerable() .Join(TheTableIDs, x => x.LeadID, ci => ci, (x, ci) => x) .Where(x => SomeString.Contains(x.Col1) == true || SomeString.Contains(x.Col2) == true) .Select(x => x.ID).ToList();
这会编译并不会抛出任何exception,但似乎忽略了SomeString.Contains
的Where
子句
使此查询有效的解决方案是什么?
谢谢。
简单 – 只要TheTAbleID包含的ID少于2100,那么这样做是不合法的。
将表切成2000块,然后分别查询每个块,可能是多个线程。
SQL在in
语句中不支持超过2100个值,但您可以使用包含超过2100行的表,这样您就可以将数据插入表中并更改查询以通过从该表中选择来检入
例如
Create TempIDs (bigint ID, uniqueidentifier guid)
guid列用于防止混合不同的用户数据
在你的代码中
Guid myKey = Guid.New(); List TheTableIDs = list of IDs (sometimes more than 2100) TheDataContext.TempIDs.InsertAllOnSubmit(TheTableIDs.select(i => new TempIDs{ID = i, Guid = mykey}); TheDataContext.SubmitChanges(); var QueryOutput = (from x in TheDataContext.SomeTable where TheDataContext.TempIDs.Contains(x.ID) && x.Col1.Contains(SomeString) || x.Col2.Contains(SomeString)) select x.ID).ToList();
如果你可以从数据库中检索id,你可以在sql中编写一个表值函数来返回id并在你的代码中对这个函数进行建模,假设它的名字是fnGetIds
。 然后在您的代码中使用它,如下所示
var QueryOutput = (from x in TheDataContext.SomeTable where TheDataContext.fnGetIds().Contains(x.ID) && x.Col1.Contains(SomeString) || x.Col2.Contains(SomeString)) select x.ID).ToList();
我得到了这个,我不能使用2100参数! 还有其他事情正在发生。
经过仔细研究,我发现我在一个循环中添加了所谓的5个参数,但是源对象没有被清除,所以要插入的对象列表变得越来越大。
Dim reportNum = 1 For Each report In wwo.wwoWeatherReport.listOfForecasts 'whack these into the regionsAndCountries db.addParameter("@forecastAirTemp" & reportNum, report.listOfhourlyForecasts(0).hourlyForecast_tempC) db.addParameter("@forecastRainFall" & reportNum, report.listOfhourlyForecasts(0).hourlyForecast_precipMM) reportNum = reportNum + 1 Next
我不得不预先对一个新的wwo对象进行Dim并对其进行排序
Dim wwo As New wwwoManager Dim reportNum = 1 ...
使用2 where子句:
List TheTableIDs = list of IDs (sometimes more than 2100) var _QueryOutput = (from x in TheDataContext.SomeTable where x.Col1.Contains(SomeString) || x.Col2.Contains(SomeString)) select x.ID).ToList(); var QueryOutput = _QueryOutput.Where(w => TheTableIDs.Contains(w)).ToList();
为了提高效率,你可以重构代码,这样只有当list包含超过2000时它才会这样做:
if (TheTableIDs.Count() > 2000) // Code Here else // Code Here
这里的问题是使用Contains ,它需要在一个单独的查询中:
List TheTableIDs = list of IDs (sometimes more than 2100) var QueryOutput = (from x in TheDataContext.SomeTable where TheTableIDs.Contains(x.ID) select x.ID).ToList(); foreach(var s in QueryOutput){ if(x.Col1.Contains(SomeString) || x.Col2.Contains(SomeString)){ //do something } }