あの例外確実に起こせるぞ!再現方法。

「ドキュメント ライブラリ」の同じユーザが閲覧できるアイテムの数が1つのフォルダで2000件超えている時にWeb画面で

<!-- #RENDER FAILED -->

と表示される件と、Microsoft.SharePointのクラスを使用したプログラミングでの

System.Data.SqlClient.SqlException: 着信の表形式のデータ ストリーム (TDS) リモート プロシージャ コール (RPC) プロトコル ストリームが不適切です。この RPC 要求に指定されたパラメータが多すぎます。最大数は 2100 です。

という例外が起こる件。kb958577(機械翻訳kb958577)
確実に再現できるC# Consoleアプリケーションを作成してみました。
まず、新規にドキュメントライブラリを作成します。

Consoleアプリケーションを作成して、必要なWSSのDLL参照をしてusing宣言を書いて、以下のメソッドを定義します。

/// <summary>
/// 同じファイルをコピーしてドキュメントライブラリに
/// </summary>
/// <param name="docLib">ドキュメントライブラリ(SPDocumentLibraryオブジェクト)</param>
/// <param name="filePath">コピー元ファイルの絶対パス</param>
/// <param name="loginName">ドキュメント作成者、更新者とするユーザ</param>
/// <param name="start">連番開始番号</param>
/// <param name="end">連番終了番号</param>
private static void UploadManyFiles(SPDocumentLibrary docLib, string  filePath, string loginName, int start, int end)
{
    SPWeb web = docLib.ParentWeb;
    SPFileCollection filecoll = web.Folders[docLib.Title].Files;
    string fileName = Path.GetFileNameWithoutExtension(filePath);
    string fileExt = Path.GetExtension(filePath);
    byte[] fileBytes = ReadAsBytes(filePath);

    SPUser user = web.EnsureUser(loginName);
    string url = "";
    SPFile file = null;
    for (int i = start; i <= end; i++)
    {
        url = string.Format("{0}/{1}{2:D4}{3}", filecoll.Folder.Url, fileName, i, fileExt);
        Console.WriteLine("{0} is uploaded by {1}.", url, user.LoginName);
        file = filecoll.Add(url, fileBytes, user, user, DateTime.Now, DateTime.Now);
        file.Item.BreakRoleInheritance(false);
        file.Item.SystemUpdate();
    }
}
/// <summary>
/// ファイルをバイト列として読み込む
/// </summary>
/// <param name="filePath">パス</param>
/// <returns>ファイルの中身のバイト列</returns>
private static byte[] ReadAsBytes(string filePath)
{
    MemoryStream ms = new MemoryStream();
    byte[] buffer = new byte[1024];
    using (BinaryReader br = new BinaryReader(new FileStream(filePath, FileMode.Open)))
    {
        while (br.Read(buffer, 0, buffer.Length) > 0)
        {
            ms.Write(buffer, 0, buffer.Length);
        }
    }
    byte[] fileBytes = ms.ToArray();
    return fileBytes;
}
  • filePathは適当なファイルたとえば、新規に作成したExcelのBook(.xls)の絶対パス
  • loginNameは投稿権限を持つユーザのログイン名とします。

Mainの内部でSPDocumentLibraryオブジェクトdocLibを取得して以下を実行。

・・・
//ドキュメント ライブラリのバージョン設定
//「このドキュメント ライブラリのファイルを編集するたびにバージョンを作成する 」で
//「   メジャーとマイナー (下書き) バージョンを作成する」を選択するのと同様。
docLib.EnableVersioning = true;
docLib.EnableMinorVersions = true;
//            docLib.DraftVersionVisibility = DraftVisibilityType.Reader;//(※1)
docLib.Update();

Console.WriteLine("EnableVersioning = {0}", docLib.EnableVersioning);
Console.WriteLine("EnableMinorVersions = {0}", docLib.EnableMinorVersions);
Console.WriteLine("DraftVersionVisibility = {0}", docLib.DraftVersionVisibility);
UploadManyFiles(docLib,filePath, loginName, 0, 2110);

//「この ドキュメント ライブラリ の下書きアイテムを表示できるユーザー」を 「アイテムを編集できるユーザー」にするのと同じ
docLib.DraftVersionVisibility = DraftVisibilityType.Author;//(※2)
docLib.Update();//(※2)
Console.WriteLine("DraftVersionVisibility = {0}", docLib.DraftVersionVisibility);
Console.WriteLine("list.Items.Count = {0}", docLib.Items.Count);//←ここで上記の例外が発生します!!!

ちなみに、(※1)の行をコメント解除して、(※2)の行をコメント化すると例外は発生しません。2009-02-20の日記のWeb画面での設定と同じことです。