7

100,000レコードのSQLテーブルを指すSharePoint外部リストがあります。リストの読み取り操作にフィルターを設定する必要があります。そうしないと、リストが機能しません。完全なリストを返そうとするとタイムアウトになります。そこで、サイズ200の制限フィルターを操作に追加しました。

これが引き起こす問題は、CAMLを使用して外部リストを照会すると、返された200エントリのみが検索され、完全なリストは検索されないことです。

リスト全体を検索したいのですが、一致するエントリは最大200個しか返されません。

どうすればこれを最もよく達成できますか?

4

6 に答える 6

2

たぶん、SharePoint-Exchangeでのこの回答が役に立ちます。 https://sharepoint.stackexchange.com/questions/31566/caml-and-external-list-pass-parameter-to-readlist-finder-method

私の考えでは、おそらくreadlist-methodを変更して、SQLテーブル全体を確実に読み取るようにする必要がありますが、readlist-methodのfilterパラメーターでWhere-parameterを指定します。何かのようなもの

擬似コード:

public static IEnumerable<YourEntity> ReadList(string param)
{
    if(string.IsNullOrEmpty(param) == true)
    {
        //Your original code thata only fetches the first 200 items
    }
    else
    {
        //Read your SQL-table with a Where ParamName = 'param' - clause
    }
}

幸運を

于 2012-04-03T07:11:40.340 に答える
2

クエリの構造とここに表示される情報に基づいて、レポートは <RowLimit>必要な機能を実装していることを示します。

RowLimit要素は、ビューの行制限を設定します。

構文

属性

  • ページング:オプションのブール値。リストがページごとのより多くのアイテムの表示をサポートしている場合はTRUE。FALSEまたは指定されていない場合、行制限は絶対的であり、他の項目を表示するためのリンクはありません。

警告:ドキュメントの注釈に注意してください。

あなたはおそらくあなたの目的のためにこれをすでに調べているでしょう(あなたの質問を引用して:「それで私は操作にサイズ200の制限フィルターを追加しました。」)。では、次の問題に移りましょう。

これが引き起こす問題は、CAMLを使用して外部リストを照会すると、返された200エントリのみが検索され、完全なリストは検索されないことです。

これは奇妙に思えます。実際に使用<RowLimit>していて、ドキュメントが正しい場合:

RowLimit要素は、ビューの行制限を設定します。

そして

<RowLimit>タグはビューのスキーマ定義(の直接の子)にあるため、タグ内にネストすることはできません<Query>

次に、制限ステートメントの保証を満たすために、ネストされたクエリがViewコンポーネントの前に実行されることが当てはまるはずです。これの当然の結果として、これにより、クエリで定義された残りのセット全体で結果のページングを実行できるようになります。

これらの原則に基づいて、次のようなページクエリを作成できます。

<View>
    <RowLimit Paged='True'>200</RowLimit>
    <Method Name='ReadList'/>
    <Query>
        <Where>
            <Contains>
                    <FieldRef Name='Name'/>
                    <Value Type='Text'>{0}</Value>
            </Contains>
        </Where>
    </Query>
    <ViewFields>
    <FieldRef Name='Name'/>
    <FieldRef Name='Id'/>
    <FieldRef Name='BdcIdentity'/>                        
    </ViewFields>
</View>

ドキュメントに記載されているように、を実装する必要があることに注意してください<PagedRowset>。これが望ましくない場合は、Paged='FALSE'上記で設定します。

これはあなたがすでに試したこととまったく同じように見えるので、私はおそらくここでは完全にベースから外れています。しかし、空間を徹底的にマッピングするために、それを提案することは害にはなりません。

于 2012-04-04T09:35:01.943 に答える
0

残念ながら、これは外部リストのクエリに関する既知の問題です。ただし、OOB Webパーツでは、ページングは​​XSLTによってサポートされます。RowLimitはXSLTでのみ機能し、CAMLクエリでは機能しません。外部リストにはサーバー側のページングは​​ありません。ページングは​​クライアント側です。つまり、SharePointはすべてのデータを取得し、ビューにフィルター制限を設定します。

于 2012-04-06T09:33:58.283 に答える
0

これは、ノーコードBCS自体が実際にそれをカットしないシナリオの1つです。これをデータベースサーバー上のストアドプロシージャとして実装するか、VisualStudioに組み込まれているカスタムBDCコネクタを使用して実装します。

于 2012-04-08T14:13:54.873 に答える
0

SQLテーブル全体を外部リストに取り込むことができない場合は、SharePointリストのように、そのデータセットをクエリできるようにする方法はありません。

ただし、これと実質的に同じシナリオで使用したソリューションを提供することはできます。これは、非常にうまく機能しています。このシナリオでは、大きなデータセットを返すのに永遠にかかるOracleデータベースにクエリを実行しています。

私たちが採用したアプローチは、ファクトリパターンを使用して、データソース(SharePointリスト、外部データベースなど)をクエリする必要がある手段を決定することでした。

以下の例は少し陳腐ですが、概念をよく示しています。

したがって、データセットのクエリ方法と返されるフィールドを定義するインターフェイスから始めます。

public interface IQueryData
{
    string ListToQuery { get; set; }
    List<MyResultObject> ExecuteQuery();
}

クエリによって返される単一のレコードを表すカスタムオブジェクトがあります

public class MyResultObject
{
    public string FileRef { get; }
    public string Title { get; set; }
    // any other fields you'd like to see potentially returned...
}

次に、SQLデータソース用にこのインターフェイスを実装するデータプロバイダーがあります。

public class SqlDataProvider : IQueryData
{
    public string ListToQuery { get { return "BigSqlTable"; } }
    public List<MyResultObject> ExecuteQuery()
    {
        // query your external data source here...
        // populate a list of MyResultObject's from the result set and return it to the consumer
    }
}

SharePointデータソースのインターフェイスを実装するデータプロバイダーもあります

public class SharePointDataProvider : IQueryData
{
    public string ListToQuery { get { return "MySharePointList"; } }
    public List<MyResultObject> ExecuteQuery()
    {
        // query your SharePoint list here, using CAML, SharePoint object model, etc...
        // populate a list of MyResultObject's from the result set and return it to the consumer
    }
}

この実装では、それぞれのデータプロバイダーでクエリのロジックと詳細をカプセル化しました。

これで、(指定されたListToQueryパラメーターに基づいて)適切なデータプロバイダーを構築するファクトリができました。

public static class QueryDataProviderFactory
{
    public static IQueryData Build(string listToQuery)
    {
        switch(listToQuery)
        {
            case "BigSqlTable": return new SqlDataProvider(); break;
            case "MySharePointList": return new SharePointDataProvider(); break;
            // you can have many other implementations here that query your data sources in different manners
        }
    }
}

最後に、ファクトリを使用してクエリを開始し、クエリするデータソースの名前を渡します。

public List<MyResultObject> RunQuery()
{
    return QueryDataProviderFactory.Build("BigSqlTable").ExecuteQuery();
}

このパターンは、外部実装を独自のデータプロバイダーにカプセル化したままにし、コンシューマーからクエリの詳細を抽象化します。コンシューマーが行う必要があるのは、照会するリストの名前を指定することだけであり、ファクトリは開始する実装を決定します。

IQueryDataインターフェースにジェネリックを実装させて、さらに拡張することもできます。

public interface IQueryData<T>
{
    string ListToQuery { get; set; }
    List<T> ExecuteQuery();
}

これにより、消費者は、返されると予想されるオブジェクトのタイプも指定できるようになります。

私たちのクエリデータインターフェイスには、実際にはさらに多くのメンバーがあり、クエリプロバイダーにさらに多くの拡張ポイントを追加していますが、この例は、ポイントを簡潔で把握しやすい方法で示していると思いました。

1年ほど前に遭遇したのとほぼ同じシナリオのようであり、この戦略は私たちにとって非常にうまく機能しているため、この提案を提供したかっただけです。

于 2012-04-08T15:22:41.093 に答える
-1

SPQueryおよびSPListItemCollectionのプロパティListItemCollectionPositionを使用します。例:

using (var web = site.OpenWeb("bla-bla"))
{
  var list = web.Lists["your_list"];
  var query = new SPQuery();
  query.Query = "your query";
  do
  {
    var items = list.GetItems(query);
    foreach(SPListItem item in items)
    {
      //your code
    }
    query.ListItemCollectionPosition = items.ListItemCollectionPosition;
  } while(query.ListItemCollectionPosition != null);
}
于 2011-08-25T13:34:11.873 に答える