4

2 つのデータベースを持つアプリケーションに取り組んでいます。

permitテーブルからのIDを参照するIDのリストを持っているオブジェクトを持っていtasksます。それを他のデータベースで呼び出しましょう。

次のクエリを実行しようとしています。

var listOfUsedIds = select taskid from Permit_Task;
Select * from task where id not in (listOfUsedIds)

このコードを実行すると、次のエラーが表示されます。

着信表形式データ ストリーム (TDS) リモート プロシージャ コール (RPC) プロトコル ストリームが正しくありません。
この RPC 要求で指定されたパラメーターが多すぎます。最大は 2100 です。

NHibernate では 2 つのデータベースに対して実行できないため、サブ選択などを実行できません。

この問題を回避する方法を教えてくれる人はいますか?

4

2 に答える 2

1
using (var tx = session.BeginTransaction())
{
    session.CreateSQLQuery("CREATE TEMP TABLE usedIds (id INT)").ExecuteUpdate();

    for (int index = 0; index < ids.Length; index++)
    {
        // TODO: batch this
        session.CreateSQLQuery("INSERT INTO usedIds VALUES (:p" + index + ")")
            .SetParameter("p" + index, id)
            .ExecuteUpdate();
    }

    session.CreateSQLQuery("CREATE INDEX usedIds_idx ON usedIds (id)").ExecuteUpdate();


    Batch batch;
    while((batch.List = session.CreateSQLQuery("SELECT id FROM tasks t WHERE 1 = (SELECT COUNT(*) FROM usedIds u WHERE u.id = t.id) LIMIT 10 OFFSET " + batch.Number).List<int>()).Count > 0)

    {
        var tasks = session.QueryOver<Task>()
            .Where(t => t.Id.IsIn(batch))
            .List();
        // Do something with the tasks
    }
    tx.Commit();
}

また

public TaskMap()
{

    Map(x => x.IsUsedCount).Formula("SELECT (SELECT COUNT(*) FROM usedIds u WHERE u.Id = Id)").LazyLoad();
}

var tasks = session.QueryOver<Task>()
    .Where(t => t.IsUsedCount == 0)
    .List();
于 2011-09-15T11:40:53.403 に答える
0

listOfUsedIdsを小さなブロック (たとえば、それぞれ 200 個の ID) に分割し、各ブロックに対してクエリを実行し、結果を取得するだけ.Concat()です。

于 2011-09-15T15:34:39.737 に答える