IIJIMASが勉強しようとしています。

これからこれから♪

目次

Blog 利用状況

ニュース

共著:




わんくま同盟 東京勉強会 #99 私の資料

個数を数えてみたい!

わんくま同盟 東京勉強会 #91 私の資料

きっと楽しいトポロジー

わんくま同盟 東京勉強会 #45 数学デー 私の資料(pptxとxlsx)

確率の不思議

わんくま同盟 東京勉強会 #37 私のLT資料

数の冪の和の式 を求めてみよう!

デブサミ09でわんくま同盟の紹介をしたスライド

わんくま同盟 東京勉強会 #26 LT祭りの私のスライド

わんくま同盟 東京勉強会 #23の私のスライド

わんくま同盟 東京勉強会 #18の私のスライド


自己紹介(仮)

IIJIMASと申します。
東京都多摩市在住です。多摩川のそばです。
猫好きです。
IIJIMASのSは何って言われます。 IIJIMASって
なんて読むかは自由です。
魚や網間企業とゲームとは無関係です。
数学とか宇宙とかの読み物とか好きです。
血液型:果汁100%A
メタボ予備軍。。。orz
Twitter

...............
MVP 審査応募ページ~ 求む、日本のMVP。
MCTS:.NET Framework 2.0: Windows アプリケーション
MCTS:.NET Framework 2.0: Windows アプリケーション

MCSD.NET:マイクロソフト認定ソリューションデベロッパー(MCSD) Microsoft .NET トラック
Microsoft Certified Solution Developer for Microsoft.NET

リンク

わんくま同盟
わんくま同盟

C#VB.NET掲示板
C#VB.NET掲示板

わんくま同盟 Blog's

ちょっと一言(仮)


書庫

日記カテゴリ

2009年3月18日 #

[SharePoint]アイテム数が多数(約2100以上)あるリストのアイテムIDをすべて列挙しようとして・・・

※注意:以下に書くことはまだ、[SharePoint]WSS3.0の累積的な更新・・・(KB961755)のパッチ未適用の環境でのことです。

あるリストで同一フォルダにアイテムが約2100以上あると、SPList.Items(SPListItemCollection)のメンバ使用するだけでも例外になってしまう場合があります。→[SharePoint]リストにアイテムが約2100件以上あると・・・(続き:再現)

このとき通常のWeb画面でもアイテムの一覧画面で

<!-- #RENDER FAILED -->

と表示されてしまいます。(kb/958577/en,kb/958577/)

このときSPListItemCollectionのCountプロパティやforeachで暗黙的に使用されるGetEnumerator メソッドでも例外になってしまいます。 一度には取得・列挙できません。

そこで、小分けに、IDの範囲を指定して分割して、たとえば100件以内ずつ複数回のクエリに分けて、取得してIDを表示する以下のサンプルプログラムを作成しました。

下のPrintAllListItemIds1とPrintAllListItemIds2はどちらも指定したリスト(ドキュメントライブラリ)のすべてのアイテムのIDを出力して最後に合計件数を出力するメソッド(のはず)です。一見するとどちらも同じ結果が期待できそうです。

[SharePoint]リストにアイテムが約2100件以上あると・・・(続き:再現)のときに作成した、直下のルートフォルダに4024件アイテムが登録されているドキュメントライブラリ(バージョン管理設定、下書きアイテムを表示できるユーザー = 「アイテムを編集できるユーザー 」)があるので、実際に実行してみました。

PrintAllListItemIds1

… … …
Number of Items : 1022

PrintAllListItemIds2

… … …
Number of Items : 4023

PrintAllListItemIds1は何度やってもこうなってしまいます。これは明らかに誤った結果です。

PrintAllListItemIds2も1件違いますが、これは別の問題です。別のユーザーがドキュメントライブラリにアップロードしたばかりでカスタムフィールドを編集していない、バージョン0.1のチェックアウトファイルと思われます。このようなドキュメントアイテムはItemsやクエリ結果に出現しません。

どうやらSPWebオブジェクトをクエリの都度生成しなおさないと、クエリを使用するだけでオブジェクトが何かおかしくなってしまうようです。


using System;
using Microsoft.SharePoint;

namespace TestSPQuery
{
    class Program
    {
        const string QUERY_BY_ID_RANGE = @"<Where>
<And>
<Geq>
  <FieldRef Name = ""ID""/>
  <Value Type = ""Counter"">{0}</Value>
</Geq>
<Lt>
  <FieldRef Name = ""ID""/>
  <Value Type = ""Counter"">{1}</Value>
</Lt>
</And>
</Where>";

        const int MaxItemID = 4500;//取得する最大IDの目安
        const int DEFAULT_ID_RANGE = 100;//1回のクエリ対象にするIDの範囲
        /// <summary>
        /// start<=ID<endというクエリ
        /// </summary>
        public static string GetIDRangeQery(int start, int end)
        {
            return string.Format(QUERY_BY_ID_RANGE, start, end);
        }

        static void Main(string[] args)
        {
            String scUrl = "(サイトコレクションURL)";
            String siteName = "サイト名";
            String listName = "リスト名";

          //PrintAllListItemIds1(scUrl, siteName, listName, DEFAULT_ID_RANGE);
          //PrintAllListItemIds2(scUrl, siteName, listName, DEFAULT_ID_RANGE);

        }

        /// <summary>
        /// 指定したリスト(ドキュメントライブラリ)のすべてのアイテムのID表示する。
        /// </summary>
        /// <param name="scUrl">サイトコレクションURL</param>
        /// <param name="siteName">サイト名</param>
        /// <param name="listName">リスト名</param>
        /// <param name="rangesize">1回のクエリ対象にするIDの範囲</param>
        private static void PrintAllListItemIds1(String scUrl, String siteName, String listName, int rangesize)
        {
            using (SPSite site = new SPSite(scUrl))
            {
                using (SPWeb web = site.AllWebs[siteName])
                {
                    SPList list = web.Lists[listName];
                    Console.WriteLine("List Title :{0}, ItemCount: {1} ", list.Title, list.ItemCount);
                    int count = 1;
                    for (int start = 0; start <= MaxItemID; start += rangesize)
                    {
                        SPQuery q = new SPQuery();
                        q.Query = GetIDRangeQery(start, start + rangesize);
                        Console.WriteLine(q.Query);
                        SPListItemCollection itemColl = list.GetItems(q);
                        foreach (SPListItem item in itemColl)
                        {
                            Console.WriteLine("No.:{0} ID: {1} ",count++, item.ID);
                        }
                    }
                    Console.WriteLine("Number of Items : {0}",count-1);
                }

            }
        }

        /// <summary>
        /// 指定したリスト(ドキュメントライブラリ)のすべてのアイテムのID表示する。
        /// </summary>
        /// <param name="scUrl">サイトコレクションURL</param>
        /// <param name="siteName">サイト名</param>
        /// <param name="listName">リスト名</param>
        /// <param name="rangesize">1回のクエリ対象にするIDの範囲</param>
        private static void PrintAllListItemIds2(String scUrl, String siteName, String listName, int rangesize)
        {
            using (SPSite site = new SPSite(scUrl))
            {
                using (SPWeb web = site.AllWebs[siteName])
                {
                    SPList list = web.Lists[listName];
                    Console.WriteLine("List Title :{0}, ItemCount: {1} ", list.Title, list.ItemCount);
                }
                int count = 1;
                for (int start = 0; start <= MaxItemID; start += rangesize)
                {
                    using (SPWeb web = site.AllWebs[siteName])//クエリの度にサイト(SPWebオブジェクト)を生成。
                    {
                        SPList list = web.Lists[listName];
                        SPQuery q = new SPQuery();
                        q.Query = GetIDRangeQery(start, start + rangesize);
                        Console.WriteLine(q.Query);
                        SPListItemCollection itemColl = list.GetItems(q);
                        foreach (SPListItem item in itemColl)
                        {
                            Console.WriteLine("No.:{0} ID: {1} ", count++, item.ID);
                        }
                    }
                }
                Console.WriteLine("Number of Items : {0}", count - 1);
            }

        }

    }
}


posted @ 11:30 | Feedback (292)