2009-03-17 45 views
51
from f in CUSTOMERS 
where depts.Contains(f.DEPT_ID) 
select f.NAME 

depts部門IDのリスト(IEnumerable<int>は)(3000のDEPTのidの周りに言って、あなたが大規模なリストを渡すまで、このクエリは正常に動作します使用した場合)(2100パラメータの上限(SQL Serverの)が含ま打撃

です)...その後、私はこのエラーを取得する:

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.

私は私のクエリを変更:

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()を使用するとエラーは修正されましたが、クエリが遅くなりました。これを解決する他の方法はありますか?本当にありがとう。

+1

[ようそう](http://stackoverflow.com/questions/567963/linq-expression-to-return-property-value/568771#568771)(それをバッチ処理についてどのように管理可能な部分に)。その他の(LINQ以外の)オプションには、CSVと「分割」UDF、およびテーブル値パラメータ(SQL2008)が含まれます。 –

+0

Mark、1から2000までのさまざまなパラメータがある場合、 'contain'の最良の代替案は何ですか?私はこれがdbのプランをたくさん作成することを知っていますが、 '<入力パラメータ>のような '%<検索フィールド>%''の使用はより多くのdbリソース時間を要するようです。私は何を使うべきですか? –

+0

2100パラメータの制限の問題はEntity Frameworkに存在しません:http://stackoverflow.com/questions/8898564/entity-framework-hitting-2100-parameter-limit – nmit026

答えて

6

質問をSQLに書き込んでエンティティを添付してみませんか?

それは私がLINQの中で働いていたので、しばらくして、しかしここにいます:

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

はもちろん、あなたがインジェクションから保護する必要がありますが、それはあまりにも難しいことではありません。

+0

ありがとうございました。私はそれを試してみましょうと私はあなたがそれがどのように行くかをお知らせします。 –

+10

警告:これは整数では問題ありませんが、文字列ではSQLインジェクションに注意してください。 –

+1

おそらくどこかにコンマを入れたいと思っています、ジョエル? –

2

LINQKit projectをチェックアウトしたいのは、この問題を解決するためにこのようなステートメントをバッチアップする方法があるからです。 PredicateBuilderを使用してローカルコレクションを小さなチャンクに分割することがアイデアだと思いますが、これを処理するより自然な方法を探していたため、ソリューションを詳しく見直していません。

残念なことに、Microsoft's response to my suggestionから、.NET Framework 4.0またはそれ以降のサービスパックで対処する予定がないというこの動作が修正されています。

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

UPDATE:

私は、これはMSDNフォーラムでLINQ to SQLまたはADO.NET Entity Frameworkのために固定することとしていたかどうかについての議論を開いてきました。これらのトピックの詳細については、これらの記事を参照し、XMLとSQL UDFを使用して私が思い付いた一時的な回避策を見てください。

1

私にも同様の問題があり、それを解決するには2つの方法があります。

  1. Intersect方法
  2. リストにない値を取得するにはIDが

に参加し、私はExceptメソッドを使用したり、参加残しました。

+2

あなたはそれを行う方法の例を教えてください。 –

10

私のソリューション(ガイド - >のGUIDの一覧):

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; 
+1

Ceilingを使用し、Skipを掛けて1だけインクリメントするのではなく、条件に対してCountを使用し、2000だけインクリメントします。また、設定可能にするために定数にします。 – webXL

関連する問題