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

deptsIEnumerable<int>は部門 IDのリスト ( ) です

このクエリは、大きなリスト (たとえば、約 3000 の部門 ID) を渡すまでは正常に機能します。その後、次のエラーが発生します。

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

4

5 に答える 5

15

私の解決策(GuidsフィルタリングしたいIDのリストです):

List<MyTestEntity> result = new List<MyTestEntity>();
for(int i = 0; i < Math.Ceiling((double)Guids.Count / 2000); i++)
{
    var nextGuids = Guids.Skip(i * 2000).Take(2000);
    result.AddRange(db.Tests.Where(x => nextGuids.Contains(x.Id)));
}
this.DataContext = result;
于 2014-02-11T17:43:23.070 に答える
6

SQL でクエリを記述し、エンティティをアタッチしてみませんか?

私がLinqで働いてからしばらく経ちましたが、ここに行きます:

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

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

于 2009-03-17T21:54:05.937 に答える
1

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

残念ながら、この動作を修正するという私の提案に対する Microsoft の回答から、 .NET Framework 4.0 やそれ以降のサービス パックでさえ、これに対処する計画はないようです。

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

アップデート:

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

于 2009-08-04T19:00:31.280 に答える
1

私は同様の問題を抱えていましたが、それを修正するには2つの方法がありました。

  1. 交差
  2. IDで参加

リストにない値を取得するには、Exceptメソッド OR left join を使用しました。

アップデート

EntityFramework 6.2 は、次のクエリを正常に実行します。

var employeeIDs = Enumerable.Range(3, 5000);
var orders =
    from order in Orders
    where employeeIDs.Contains((int)order.EmployeeID)
    select order;
于 2012-11-12T14:05:45.190 に答える
-1

Linq によって生成された IN ステートメントにパラメーターとして渡す前に、部門のリストを小さなセットに分割することができます。ここを参照してください:

大きな IEnumerable をアイテムの固定量の小さな IEnumerable に分割する

于 2015-05-23T15:45:38.967 に答える